Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as select.


   1"""
   2## Expressions
   3
   4Every AST node in SQLGlot is represented by a subclass of `Expression`.
   5
   6This module contains the implementation of all supported `Expression` types. Additionally,
   7it exposes a number of helper functions, which are mainly used to programmatically build
   8SQL expressions, such as `sqlglot.expressions.select`.
   9
  10----
  11"""
  12
  13from __future__ import annotations
  14
  15import datetime
  16import math
  17import numbers
  18import re
  19import textwrap
  20import typing as t
  21from collections import deque
  22from copy import deepcopy
  23from enum import auto
  24from functools import reduce
  25
  26from sqlglot.errors import ErrorLevel, ParseError
  27from sqlglot.helper import (
  28    AutoName,
  29    camel_to_snake_case,
  30    ensure_collection,
  31    ensure_list,
  32    is_int,
  33    seq_get,
  34    subclasses,
  35)
  36from sqlglot.tokens import Token
  37
  38if t.TYPE_CHECKING:
  39    from sqlglot._typing import E, Lit
  40    from sqlglot.dialects.dialect import DialectType
  41
  42    Q = t.TypeVar("Q", bound="Query")
  43
  44
  45class _Expression(type):
  46    def __new__(cls, clsname, bases, attrs):
  47        klass = super().__new__(cls, clsname, bases, attrs)
  48
  49        # When an Expression class is created, its key is automatically set to be
  50        # the lowercase version of the class' name.
  51        klass.key = clsname.lower()
  52
  53        # This is so that docstrings are not inherited in pdoc
  54        klass.__doc__ = klass.__doc__ or ""
  55
  56        return klass
  57
  58
  59SQLGLOT_META = "sqlglot.meta"
  60TABLE_PARTS = ("this", "db", "catalog")
  61
  62
  63class Expression(metaclass=_Expression):
  64    """
  65    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  66    context, such as its child expressions, their names (arg keys), and whether a given child expression
  67    is optional or not.
  68
  69    Attributes:
  70        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  71            and representing expressions as strings.
  72        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  73            arg keys to booleans that indicate whether the corresponding args are optional.
  74        parent: a reference to the parent expression (or None, in case of root expressions).
  75        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  76            uses to refer to it.
  77        index: the index of an expression if it is inside of a list argument in its parent.
  78        comments: a list of comments that are associated with a given expression. This is used in
  79            order to preserve comments when transpiling SQL code.
  80        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  81            optimizer, in order to enable some transformations that require type information.
  82        meta: a dictionary that can be used to store useful metadata for a given expression.
  83
  84    Example:
  85        >>> class Foo(Expression):
  86        ...     arg_types = {"this": True, "expression": False}
  87
  88        The above definition informs us that Foo is an Expression that requires an argument called
  89        "this" and may also optionally receive an argument called "expression".
  90
  91    Args:
  92        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
  93    """
  94
  95    key = "expression"
  96    arg_types = {"this": True}
  97    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
  98
  99    def __init__(self, **args: t.Any):
 100        self.args: t.Dict[str, t.Any] = args
 101        self.parent: t.Optional[Expression] = None
 102        self.arg_key: t.Optional[str] = None
 103        self.index: t.Optional[int] = None
 104        self.comments: t.Optional[t.List[str]] = None
 105        self._type: t.Optional[DataType] = None
 106        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 107        self._hash: t.Optional[int] = None
 108
 109        for arg_key, value in self.args.items():
 110            self._set_parent(arg_key, value)
 111
 112    def __eq__(self, other) -> bool:
 113        return type(self) is type(other) and hash(self) == hash(other)
 114
 115    @property
 116    def hashable_args(self) -> t.Any:
 117        return frozenset(
 118            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 119            for k, v in self.args.items()
 120            if not (v is None or v is False or (type(v) is list and not v))
 121        )
 122
 123    def __hash__(self) -> int:
 124        if self._hash is not None:
 125            return self._hash
 126
 127        return hash((self.__class__, self.hashable_args))
 128
 129    @property
 130    def this(self) -> t.Any:
 131        """
 132        Retrieves the argument with key "this".
 133        """
 134        return self.args.get("this")
 135
 136    @property
 137    def expression(self) -> t.Any:
 138        """
 139        Retrieves the argument with key "expression".
 140        """
 141        return self.args.get("expression")
 142
 143    @property
 144    def expressions(self) -> t.List[t.Any]:
 145        """
 146        Retrieves the argument with key "expressions".
 147        """
 148        return self.args.get("expressions") or []
 149
 150    def text(self, key) -> str:
 151        """
 152        Returns a textual representation of the argument corresponding to "key". This can only be used
 153        for args that are strings or leaf Expression instances, such as identifiers and literals.
 154        """
 155        field = self.args.get(key)
 156        if isinstance(field, str):
 157            return field
 158        if isinstance(field, (Identifier, Literal, Var)):
 159            return field.this
 160        if isinstance(field, (Star, Null)):
 161            return field.name
 162        return ""
 163
 164    @property
 165    def is_string(self) -> bool:
 166        """
 167        Checks whether a Literal expression is a string.
 168        """
 169        return isinstance(self, Literal) and self.args["is_string"]
 170
 171    @property
 172    def is_number(self) -> bool:
 173        """
 174        Checks whether a Literal expression is a number.
 175        """
 176        return isinstance(self, Literal) and not self.args["is_string"]
 177
 178    @property
 179    def is_int(self) -> bool:
 180        """
 181        Checks whether a Literal expression is an integer.
 182        """
 183        return self.is_number and is_int(self.name)
 184
 185    @property
 186    def is_star(self) -> bool:
 187        """Checks whether an expression is a star."""
 188        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 189
 190    @property
 191    def alias(self) -> str:
 192        """
 193        Returns the alias of the expression, or an empty string if it's not aliased.
 194        """
 195        if isinstance(self.args.get("alias"), TableAlias):
 196            return self.args["alias"].name
 197        return self.text("alias")
 198
 199    @property
 200    def alias_column_names(self) -> t.List[str]:
 201        table_alias = self.args.get("alias")
 202        if not table_alias:
 203            return []
 204        return [c.name for c in table_alias.args.get("columns") or []]
 205
 206    @property
 207    def name(self) -> str:
 208        return self.text("this")
 209
 210    @property
 211    def alias_or_name(self) -> str:
 212        return self.alias or self.name
 213
 214    @property
 215    def output_name(self) -> str:
 216        """
 217        Name of the output column if this expression is a selection.
 218
 219        If the Expression has no output name, an empty string is returned.
 220
 221        Example:
 222            >>> from sqlglot import parse_one
 223            >>> parse_one("SELECT a").expressions[0].output_name
 224            'a'
 225            >>> parse_one("SELECT b AS c").expressions[0].output_name
 226            'c'
 227            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 228            ''
 229        """
 230        return ""
 231
 232    @property
 233    def type(self) -> t.Optional[DataType]:
 234        return self._type
 235
 236    @type.setter
 237    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 238        if dtype and not isinstance(dtype, DataType):
 239            dtype = DataType.build(dtype)
 240        self._type = dtype  # type: ignore
 241
 242    def is_type(self, *dtypes) -> bool:
 243        return self.type is not None and self.type.is_type(*dtypes)
 244
 245    def is_leaf(self) -> bool:
 246        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 247
 248    @property
 249    def meta(self) -> t.Dict[str, t.Any]:
 250        if self._meta is None:
 251            self._meta = {}
 252        return self._meta
 253
 254    def __deepcopy__(self, memo):
 255        root = self.__class__()
 256        stack = [(self, root)]
 257
 258        while stack:
 259            node, copy = stack.pop()
 260
 261            if node.comments is not None:
 262                copy.comments = deepcopy(node.comments)
 263            if node._type is not None:
 264                copy._type = deepcopy(node._type)
 265            if node._meta is not None:
 266                copy._meta = deepcopy(node._meta)
 267            if node._hash is not None:
 268                copy._hash = node._hash
 269
 270            for k, vs in node.args.items():
 271                if hasattr(vs, "parent"):
 272                    stack.append((vs, vs.__class__()))
 273                    copy.set(k, stack[-1][-1])
 274                elif type(vs) is list:
 275                    copy.args[k] = []
 276
 277                    for v in vs:
 278                        if hasattr(v, "parent"):
 279                            stack.append((v, v.__class__()))
 280                            copy.append(k, stack[-1][-1])
 281                        else:
 282                            copy.append(k, v)
 283                else:
 284                    copy.args[k] = vs
 285
 286        return root
 287
 288    def copy(self):
 289        """
 290        Returns a deep copy of the expression.
 291        """
 292        return deepcopy(self)
 293
 294    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
 295        if self.comments is None:
 296            self.comments = []
 297        if comments:
 298            for comment in comments:
 299                _, *meta = comment.split(SQLGLOT_META)
 300                if meta:
 301                    for kv in "".join(meta).split(","):
 302                        k, *v = kv.split("=")
 303                        value = v[0].strip() if v else True
 304                        self.meta[k.strip()] = value
 305                self.comments.append(comment)
 306
 307    def append(self, arg_key: str, value: t.Any) -> None:
 308        """
 309        Appends value to arg_key if it's a list or sets it as a new list.
 310
 311        Args:
 312            arg_key (str): name of the list expression arg
 313            value (Any): value to append to the list
 314        """
 315        if type(self.args.get(arg_key)) is not list:
 316            self.args[arg_key] = []
 317        self._set_parent(arg_key, value)
 318        values = self.args[arg_key]
 319        if hasattr(value, "parent"):
 320            value.index = len(values)
 321        values.append(value)
 322
 323    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 324        """
 325        Sets arg_key to value.
 326
 327        Args:
 328            arg_key: name of the expression arg.
 329            value: value to set the arg to.
 330            index: if the arg is a list, this specifies what position to add the value in it.
 331        """
 332        if index is not None:
 333            expressions = self.args.get(arg_key) or []
 334
 335            if seq_get(expressions, index) is None:
 336                return
 337            if value is None:
 338                expressions.pop(index)
 339                for v in expressions[index:]:
 340                    v.index = v.index - 1
 341                return
 342
 343            if isinstance(value, list):
 344                expressions.pop(index)
 345                expressions[index:index] = value
 346            else:
 347                expressions[index] = value
 348
 349            value = expressions
 350        elif value is None:
 351            self.args.pop(arg_key, None)
 352            return
 353
 354        self.args[arg_key] = value
 355        self._set_parent(arg_key, value, index)
 356
 357    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 358        if hasattr(value, "parent"):
 359            value.parent = self
 360            value.arg_key = arg_key
 361            value.index = index
 362        elif type(value) is list:
 363            for index, v in enumerate(value):
 364                if hasattr(v, "parent"):
 365                    v.parent = self
 366                    v.arg_key = arg_key
 367                    v.index = index
 368
 369    @property
 370    def depth(self) -> int:
 371        """
 372        Returns the depth of this tree.
 373        """
 374        if self.parent:
 375            return self.parent.depth + 1
 376        return 0
 377
 378    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 379        """Yields the key and expression for all arguments, exploding list args."""
 380        # remove tuple when python 3.7 is deprecated
 381        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
 382            if type(vs) is list:
 383                for v in reversed(vs) if reverse else vs:
 384                    if hasattr(v, "parent"):
 385                        yield v
 386            else:
 387                if hasattr(vs, "parent"):
 388                    yield vs
 389
 390    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 391        """
 392        Returns the first node in this tree which matches at least one of
 393        the specified types.
 394
 395        Args:
 396            expression_types: the expression type(s) to match.
 397            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 398
 399        Returns:
 400            The node which matches the criteria or None if no such node was found.
 401        """
 402        return next(self.find_all(*expression_types, bfs=bfs), None)
 403
 404    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 405        """
 406        Returns a generator object which visits all nodes in this tree and only
 407        yields those that match at least one of the specified expression types.
 408
 409        Args:
 410            expression_types: the expression type(s) to match.
 411            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 412
 413        Returns:
 414            The generator object.
 415        """
 416        for expression in self.walk(bfs=bfs):
 417            if isinstance(expression, expression_types):
 418                yield expression
 419
 420    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 421        """
 422        Returns a nearest parent matching expression_types.
 423
 424        Args:
 425            expression_types: the expression type(s) to match.
 426
 427        Returns:
 428            The parent node.
 429        """
 430        ancestor = self.parent
 431        while ancestor and not isinstance(ancestor, expression_types):
 432            ancestor = ancestor.parent
 433        return ancestor  # type: ignore
 434
 435    @property
 436    def parent_select(self) -> t.Optional[Select]:
 437        """
 438        Returns the parent select statement.
 439        """
 440        return self.find_ancestor(Select)
 441
 442    @property
 443    def same_parent(self) -> bool:
 444        """Returns if the parent is the same class as itself."""
 445        return type(self.parent) is self.__class__
 446
 447    def root(self) -> Expression:
 448        """
 449        Returns the root expression of this tree.
 450        """
 451        expression = self
 452        while expression.parent:
 453            expression = expression.parent
 454        return expression
 455
 456    def walk(
 457        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 458    ) -> t.Iterator[Expression]:
 459        """
 460        Returns a generator object which visits all nodes in this tree.
 461
 462        Args:
 463            bfs (bool): if set to True the BFS traversal order will be applied,
 464                otherwise the DFS traversal will be used instead.
 465            prune ((node, parent, arg_key) -> bool): callable that returns True if
 466                the generator should stop traversing this branch of the tree.
 467
 468        Returns:
 469            the generator object.
 470        """
 471        if bfs:
 472            yield from self.bfs(prune=prune)
 473        else:
 474            yield from self.dfs(prune=prune)
 475
 476    def dfs(
 477        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 478    ) -> t.Iterator[Expression]:
 479        """
 480        Returns a generator object which visits all nodes in this tree in
 481        the DFS (Depth-first) order.
 482
 483        Returns:
 484            The generator object.
 485        """
 486        stack = [self]
 487
 488        while stack:
 489            node = stack.pop()
 490
 491            yield node
 492
 493            if prune and prune(node):
 494                continue
 495
 496            for v in node.iter_expressions(reverse=True):
 497                stack.append(v)
 498
 499    def bfs(
 500        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 501    ) -> t.Iterator[Expression]:
 502        """
 503        Returns a generator object which visits all nodes in this tree in
 504        the BFS (Breadth-first) order.
 505
 506        Returns:
 507            The generator object.
 508        """
 509        queue = deque([self])
 510
 511        while queue:
 512            node = queue.popleft()
 513
 514            yield node
 515
 516            if prune and prune(node):
 517                continue
 518
 519            for v in node.iter_expressions():
 520                queue.append(v)
 521
 522    def unnest(self):
 523        """
 524        Returns the first non parenthesis child or self.
 525        """
 526        expression = self
 527        while type(expression) is Paren:
 528            expression = expression.this
 529        return expression
 530
 531    def unalias(self):
 532        """
 533        Returns the inner expression if this is an Alias.
 534        """
 535        if isinstance(self, Alias):
 536            return self.this
 537        return self
 538
 539    def unnest_operands(self):
 540        """
 541        Returns unnested operands as a tuple.
 542        """
 543        return tuple(arg.unnest() for arg in self.iter_expressions())
 544
 545    def flatten(self, unnest=True):
 546        """
 547        Returns a generator which yields child nodes whose parents are the same class.
 548
 549        A AND B AND C -> [A, B, C]
 550        """
 551        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 552            if type(node) is not self.__class__:
 553                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 554
 555    def __str__(self) -> str:
 556        return self.sql()
 557
 558    def __repr__(self) -> str:
 559        return _to_s(self)
 560
 561    def to_s(self) -> str:
 562        """
 563        Same as __repr__, but includes additional information which can be useful
 564        for debugging, like empty or missing args and the AST nodes' object IDs.
 565        """
 566        return _to_s(self, verbose=True)
 567
 568    def sql(self, dialect: DialectType = None, **opts) -> str:
 569        """
 570        Returns SQL string representation of this tree.
 571
 572        Args:
 573            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 574            opts: other `sqlglot.generator.Generator` options.
 575
 576        Returns:
 577            The SQL string.
 578        """
 579        from sqlglot.dialects import Dialect
 580
 581        return Dialect.get_or_raise(dialect).generate(self, **opts)
 582
 583    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 584        """
 585        Visits all tree nodes (excluding already transformed ones)
 586        and applies the given transformation function to each node.
 587
 588        Args:
 589            fun (function): a function which takes a node as an argument and returns a
 590                new transformed node or the same node without modifications. If the function
 591                returns None, then the corresponding node will be removed from the syntax tree.
 592            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
 593                modified in place.
 594
 595        Returns:
 596            The transformed tree.
 597        """
 598        root = None
 599        new_node = None
 600
 601        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 602            parent, arg_key, index = node.parent, node.arg_key, node.index
 603            new_node = fun(node, *args, **kwargs)
 604
 605            if not root:
 606                root = new_node
 607            elif new_node is not node:
 608                parent.set(arg_key, new_node, index)
 609
 610        assert root
 611        return root.assert_is(Expression)
 612
 613    @t.overload
 614    def replace(self, expression: E) -> E: ...
 615
 616    @t.overload
 617    def replace(self, expression: None) -> None: ...
 618
 619    def replace(self, expression):
 620        """
 621        Swap out this expression with a new expression.
 622
 623        For example::
 624
 625            >>> tree = Select().select("x").from_("tbl")
 626            >>> tree.find(Column).replace(column("y"))
 627            Column(
 628              this=Identifier(this=y, quoted=False))
 629            >>> tree.sql()
 630            'SELECT y FROM tbl'
 631
 632        Args:
 633            expression: new node
 634
 635        Returns:
 636            The new expression or expressions.
 637        """
 638        parent = self.parent
 639
 640        if not parent or parent is expression:
 641            return expression
 642
 643        key = self.arg_key
 644        value = parent.args.get(key)
 645
 646        if type(expression) is list and isinstance(value, Expression):
 647            # We are trying to replace an Expression with a list, so it's assumed that
 648            # the intention was to really replace the parent of this expression.
 649            value.parent.replace(expression)
 650        else:
 651            parent.set(key, expression, self.index)
 652
 653        if expression is not self:
 654            self.parent = None
 655            self.arg_key = None
 656            self.index = None
 657
 658        return expression
 659
 660    def pop(self: E) -> E:
 661        """
 662        Remove this expression from its AST.
 663
 664        Returns:
 665            The popped expression.
 666        """
 667        self.replace(None)
 668        return self
 669
 670    def assert_is(self, type_: t.Type[E]) -> E:
 671        """
 672        Assert that this `Expression` is an instance of `type_`.
 673
 674        If it is NOT an instance of `type_`, this raises an assertion error.
 675        Otherwise, this returns this expression.
 676
 677        Examples:
 678            This is useful for type security in chained expressions:
 679
 680            >>> import sqlglot
 681            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 682            'SELECT x, z FROM y'
 683        """
 684        if not isinstance(self, type_):
 685            raise AssertionError(f"{self} is not {type_}.")
 686        return self
 687
 688    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 689        """
 690        Checks if this expression is valid (e.g. all mandatory args are set).
 691
 692        Args:
 693            args: a sequence of values that were used to instantiate a Func expression. This is used
 694                to check that the provided arguments don't exceed the function argument limit.
 695
 696        Returns:
 697            A list of error messages for all possible errors that were found.
 698        """
 699        errors: t.List[str] = []
 700
 701        for k in self.args:
 702            if k not in self.arg_types:
 703                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 704        for k, mandatory in self.arg_types.items():
 705            v = self.args.get(k)
 706            if mandatory and (v is None or (isinstance(v, list) and not v)):
 707                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 708
 709        if (
 710            args
 711            and isinstance(self, Func)
 712            and len(args) > len(self.arg_types)
 713            and not self.is_var_len_args
 714        ):
 715            errors.append(
 716                f"The number of provided arguments ({len(args)}) is greater than "
 717                f"the maximum number of supported arguments ({len(self.arg_types)})"
 718            )
 719
 720        return errors
 721
 722    def dump(self):
 723        """
 724        Dump this Expression to a JSON-serializable dict.
 725        """
 726        from sqlglot.serde import dump
 727
 728        return dump(self)
 729
 730    @classmethod
 731    def load(cls, obj):
 732        """
 733        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 734        """
 735        from sqlglot.serde import load
 736
 737        return load(obj)
 738
 739    def and_(
 740        self,
 741        *expressions: t.Optional[ExpOrStr],
 742        dialect: DialectType = None,
 743        copy: bool = True,
 744        **opts,
 745    ) -> Condition:
 746        """
 747        AND this condition with one or multiple expressions.
 748
 749        Example:
 750            >>> condition("x=1").and_("y=1").sql()
 751            'x = 1 AND y = 1'
 752
 753        Args:
 754            *expressions: the SQL code strings to parse.
 755                If an `Expression` instance is passed, it will be used as-is.
 756            dialect: the dialect used to parse the input expression.
 757            copy: whether to copy the involved expressions (only applies to Expressions).
 758            opts: other options to use to parse the input expressions.
 759
 760        Returns:
 761            The new And condition.
 762        """
 763        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)
 764
 765    def or_(
 766        self,
 767        *expressions: t.Optional[ExpOrStr],
 768        dialect: DialectType = None,
 769        copy: bool = True,
 770        **opts,
 771    ) -> Condition:
 772        """
 773        OR this condition with one or multiple expressions.
 774
 775        Example:
 776            >>> condition("x=1").or_("y=1").sql()
 777            'x = 1 OR y = 1'
 778
 779        Args:
 780            *expressions: the SQL code strings to parse.
 781                If an `Expression` instance is passed, it will be used as-is.
 782            dialect: the dialect used to parse the input expression.
 783            copy: whether to copy the involved expressions (only applies to Expressions).
 784            opts: other options to use to parse the input expressions.
 785
 786        Returns:
 787            The new Or condition.
 788        """
 789        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)
 790
 791    def not_(self, copy: bool = True):
 792        """
 793        Wrap this condition with NOT.
 794
 795        Example:
 796            >>> condition("x=1").not_().sql()
 797            'NOT x = 1'
 798
 799        Args:
 800            copy: whether to copy this object.
 801
 802        Returns:
 803            The new Not instance.
 804        """
 805        return not_(self, copy=copy)
 806
 807    def as_(
 808        self,
 809        alias: str | Identifier,
 810        quoted: t.Optional[bool] = None,
 811        dialect: DialectType = None,
 812        copy: bool = True,
 813        **opts,
 814    ) -> Alias:
 815        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 816
 817    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 818        this = self.copy()
 819        other = convert(other, copy=True)
 820        if not isinstance(this, klass) and not isinstance(other, klass):
 821            this = _wrap(this, Binary)
 822            other = _wrap(other, Binary)
 823        if reverse:
 824            return klass(this=other, expression=this)
 825        return klass(this=this, expression=other)
 826
 827    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 828        return Bracket(
 829            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 830        )
 831
 832    def __iter__(self) -> t.Iterator:
 833        if "expressions" in self.arg_types:
 834            return iter(self.args.get("expressions") or [])
 835        # We define this because __getitem__ converts Expression into an iterable, which is
 836        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 837        # See: https://peps.python.org/pep-0234/
 838        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 839
 840    def isin(
 841        self,
 842        *expressions: t.Any,
 843        query: t.Optional[ExpOrStr] = None,
 844        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 845        copy: bool = True,
 846        **opts,
 847    ) -> In:
 848        return In(
 849            this=maybe_copy(self, copy),
 850            expressions=[convert(e, copy=copy) for e in expressions],
 851            query=maybe_parse(query, copy=copy, **opts) if query else None,
 852            unnest=(
 853                Unnest(
 854                    expressions=[
 855                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 856                        for e in ensure_list(unnest)
 857                    ]
 858                )
 859                if unnest
 860                else None
 861            ),
 862        )
 863
 864    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 865        return Between(
 866            this=maybe_copy(self, copy),
 867            low=convert(low, copy=copy, **opts),
 868            high=convert(high, copy=copy, **opts),
 869        )
 870
 871    def is_(self, other: ExpOrStr) -> Is:
 872        return self._binop(Is, other)
 873
 874    def like(self, other: ExpOrStr) -> Like:
 875        return self._binop(Like, other)
 876
 877    def ilike(self, other: ExpOrStr) -> ILike:
 878        return self._binop(ILike, other)
 879
 880    def eq(self, other: t.Any) -> EQ:
 881        return self._binop(EQ, other)
 882
 883    def neq(self, other: t.Any) -> NEQ:
 884        return self._binop(NEQ, other)
 885
 886    def rlike(self, other: ExpOrStr) -> RegexpLike:
 887        return self._binop(RegexpLike, other)
 888
 889    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 890        div = self._binop(Div, other)
 891        div.args["typed"] = typed
 892        div.args["safe"] = safe
 893        return div
 894
 895    def asc(self, nulls_first: bool = True) -> Ordered:
 896        return Ordered(this=self.copy(), nulls_first=nulls_first)
 897
 898    def desc(self, nulls_first: bool = False) -> Ordered:
 899        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 900
 901    def __lt__(self, other: t.Any) -> LT:
 902        return self._binop(LT, other)
 903
 904    def __le__(self, other: t.Any) -> LTE:
 905        return self._binop(LTE, other)
 906
 907    def __gt__(self, other: t.Any) -> GT:
 908        return self._binop(GT, other)
 909
 910    def __ge__(self, other: t.Any) -> GTE:
 911        return self._binop(GTE, other)
 912
 913    def __add__(self, other: t.Any) -> Add:
 914        return self._binop(Add, other)
 915
 916    def __radd__(self, other: t.Any) -> Add:
 917        return self._binop(Add, other, reverse=True)
 918
 919    def __sub__(self, other: t.Any) -> Sub:
 920        return self._binop(Sub, other)
 921
 922    def __rsub__(self, other: t.Any) -> Sub:
 923        return self._binop(Sub, other, reverse=True)
 924
 925    def __mul__(self, other: t.Any) -> Mul:
 926        return self._binop(Mul, other)
 927
 928    def __rmul__(self, other: t.Any) -> Mul:
 929        return self._binop(Mul, other, reverse=True)
 930
 931    def __truediv__(self, other: t.Any) -> Div:
 932        return self._binop(Div, other)
 933
 934    def __rtruediv__(self, other: t.Any) -> Div:
 935        return self._binop(Div, other, reverse=True)
 936
 937    def __floordiv__(self, other: t.Any) -> IntDiv:
 938        return self._binop(IntDiv, other)
 939
 940    def __rfloordiv__(self, other: t.Any) -> IntDiv:
 941        return self._binop(IntDiv, other, reverse=True)
 942
 943    def __mod__(self, other: t.Any) -> Mod:
 944        return self._binop(Mod, other)
 945
 946    def __rmod__(self, other: t.Any) -> Mod:
 947        return self._binop(Mod, other, reverse=True)
 948
 949    def __pow__(self, other: t.Any) -> Pow:
 950        return self._binop(Pow, other)
 951
 952    def __rpow__(self, other: t.Any) -> Pow:
 953        return self._binop(Pow, other, reverse=True)
 954
 955    def __and__(self, other: t.Any) -> And:
 956        return self._binop(And, other)
 957
 958    def __rand__(self, other: t.Any) -> And:
 959        return self._binop(And, other, reverse=True)
 960
 961    def __or__(self, other: t.Any) -> Or:
 962        return self._binop(Or, other)
 963
 964    def __ror__(self, other: t.Any) -> Or:
 965        return self._binop(Or, other, reverse=True)
 966
 967    def __neg__(self) -> Neg:
 968        return Neg(this=_wrap(self.copy(), Binary))
 969
 970    def __invert__(self) -> Not:
 971        return not_(self.copy())
 972
 973
 974IntoType = t.Union[
 975    str,
 976    t.Type[Expression],
 977    t.Collection[t.Union[str, t.Type[Expression]]],
 978]
 979ExpOrStr = t.Union[str, Expression]
 980
 981
 982class Condition(Expression):
 983    """Logical conditions like x AND y, or simply x"""
 984
 985
 986class Predicate(Condition):
 987    """Relationships like x = y, x > 1, x >= y."""
 988
 989
 990class DerivedTable(Expression):
 991    @property
 992    def selects(self) -> t.List[Expression]:
 993        return self.this.selects if isinstance(self.this, Query) else []
 994
 995    @property
 996    def named_selects(self) -> t.List[str]:
 997        return [select.output_name for select in self.selects]
 998
 999
1000class Query(Expression):
1001    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1002        """
1003        Returns a `Subquery` that wraps around this query.
1004
1005        Example:
1006            >>> subquery = Select().select("x").from_("tbl").subquery()
1007            >>> Select().select("x").from_(subquery).sql()
1008            'SELECT x FROM (SELECT x FROM tbl)'
1009
1010        Args:
1011            alias: an optional alias for the subquery.
1012            copy: if `False`, modify this expression instance in-place.
1013        """
1014        instance = maybe_copy(self, copy)
1015        if not isinstance(alias, Expression):
1016            alias = TableAlias(this=to_identifier(alias)) if alias else None
1017
1018        return Subquery(this=instance, alias=alias)
1019
1020    def limit(
1021        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1022    ) -> Select:
1023        """
1024        Adds a LIMIT clause to this query.
1025
1026        Example:
1027            >>> select("1").union(select("1")).limit(1).sql()
1028            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1029
1030        Args:
1031            expression: the SQL code string to parse.
1032                This can also be an integer.
1033                If a `Limit` instance is passed, it will be used as-is.
1034                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1035            dialect: the dialect used to parse the input expression.
1036            copy: if `False`, modify this expression instance in-place.
1037            opts: other options to use to parse the input expressions.
1038
1039        Returns:
1040            A limited Select expression.
1041        """
1042        return (
1043            select("*")
1044            .from_(self.subquery(alias="_l_0", copy=copy))
1045            .limit(expression, dialect=dialect, copy=False, **opts)
1046        )
1047
1048    @property
1049    def ctes(self) -> t.List[CTE]:
1050        """Returns a list of all the CTEs attached to this query."""
1051        with_ = self.args.get("with")
1052        return with_.expressions if with_ else []
1053
1054    @property
1055    def selects(self) -> t.List[Expression]:
1056        """Returns the query's projections."""
1057        raise NotImplementedError("Query objects must implement `selects`")
1058
1059    @property
1060    def named_selects(self) -> t.List[str]:
1061        """Returns the output names of the query's projections."""
1062        raise NotImplementedError("Query objects must implement `named_selects`")
1063
1064    def select(
1065        self: Q,
1066        *expressions: t.Optional[ExpOrStr],
1067        append: bool = True,
1068        dialect: DialectType = None,
1069        copy: bool = True,
1070        **opts,
1071    ) -> Q:
1072        """
1073        Append to or set the SELECT expressions.
1074
1075        Example:
1076            >>> Select().select("x", "y").sql()
1077            'SELECT x, y'
1078
1079        Args:
1080            *expressions: the SQL code strings to parse.
1081                If an `Expression` instance is passed, it will be used as-is.
1082            append: if `True`, add to any existing expressions.
1083                Otherwise, this resets the expressions.
1084            dialect: the dialect used to parse the input expressions.
1085            copy: if `False`, modify this expression instance in-place.
1086            opts: other options to use to parse the input expressions.
1087
1088        Returns:
1089            The modified Query expression.
1090        """
1091        raise NotImplementedError("Query objects must implement `select`")
1092
1093    def with_(
1094        self: Q,
1095        alias: ExpOrStr,
1096        as_: ExpOrStr,
1097        recursive: t.Optional[bool] = None,
1098        append: bool = True,
1099        dialect: DialectType = None,
1100        copy: bool = True,
1101        **opts,
1102    ) -> Q:
1103        """
1104        Append to or set the common table expressions.
1105
1106        Example:
1107            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1108            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1109
1110        Args:
1111            alias: the SQL code string to parse as the table name.
1112                If an `Expression` instance is passed, this is used as-is.
1113            as_: the SQL code string to parse as the table expression.
1114                If an `Expression` instance is passed, it will be used as-is.
1115            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1116            append: if `True`, add to any existing expressions.
1117                Otherwise, this resets the expressions.
1118            dialect: the dialect used to parse the input expression.
1119            copy: if `False`, modify this expression instance in-place.
1120            opts: other options to use to parse the input expressions.
1121
1122        Returns:
1123            The modified expression.
1124        """
1125        return _apply_cte_builder(
1126            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1127        )
1128
1129    def union(
1130        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1131    ) -> Union:
1132        """
1133        Builds a UNION expression.
1134
1135        Example:
1136            >>> import sqlglot
1137            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1138            'SELECT * FROM foo UNION SELECT * FROM bla'
1139
1140        Args:
1141            expression: the SQL code string.
1142                If an `Expression` instance is passed, it will be used as-is.
1143            distinct: set the DISTINCT flag if and only if this is true.
1144            dialect: the dialect used to parse the input expression.
1145            opts: other options to use to parse the input expressions.
1146
1147        Returns:
1148            The new Union expression.
1149        """
1150        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1151
1152    def intersect(
1153        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1154    ) -> Intersect:
1155        """
1156        Builds an INTERSECT expression.
1157
1158        Example:
1159            >>> import sqlglot
1160            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1161            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1162
1163        Args:
1164            expression: the SQL code string.
1165                If an `Expression` instance is passed, it will be used as-is.
1166            distinct: set the DISTINCT flag if and only if this is true.
1167            dialect: the dialect used to parse the input expression.
1168            opts: other options to use to parse the input expressions.
1169
1170        Returns:
1171            The new Intersect expression.
1172        """
1173        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1174
1175    def except_(
1176        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1177    ) -> Except:
1178        """
1179        Builds an EXCEPT expression.
1180
1181        Example:
1182            >>> import sqlglot
1183            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1184            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1185
1186        Args:
1187            expression: the SQL code string.
1188                If an `Expression` instance is passed, it will be used as-is.
1189            distinct: set the DISTINCT flag if and only if this is true.
1190            dialect: the dialect used to parse the input expression.
1191            opts: other options to use to parse the input expressions.
1192
1193        Returns:
1194            The new Except expression.
1195        """
1196        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1197
1198
1199class UDTF(DerivedTable):
1200    @property
1201    def selects(self) -> t.List[Expression]:
1202        alias = self.args.get("alias")
1203        return alias.columns if alias else []
1204
1205
1206class Cache(Expression):
1207    arg_types = {
1208        "this": True,
1209        "lazy": False,
1210        "options": False,
1211        "expression": False,
1212    }
1213
1214
1215class Uncache(Expression):
1216    arg_types = {"this": True, "exists": False}
1217
1218
1219class Refresh(Expression):
1220    pass
1221
1222
1223class DDL(Expression):
1224    @property
1225    def ctes(self) -> t.List[CTE]:
1226        """Returns a list of all the CTEs attached to this statement."""
1227        with_ = self.args.get("with")
1228        return with_.expressions if with_ else []
1229
1230    @property
1231    def selects(self) -> t.List[Expression]:
1232        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1233        return self.expression.selects if isinstance(self.expression, Query) else []
1234
1235    @property
1236    def named_selects(self) -> t.List[str]:
1237        """
1238        If this statement contains a query (e.g. a CTAS), this returns the output
1239        names of the query's projections.
1240        """
1241        return self.expression.named_selects if isinstance(self.expression, Query) else []
1242
1243
1244class DML(Expression):
1245    def returning(
1246        self,
1247        expression: ExpOrStr,
1248        dialect: DialectType = None,
1249        copy: bool = True,
1250        **opts,
1251    ) -> DML:
1252        """
1253        Set the RETURNING expression. Not supported by all dialects.
1254
1255        Example:
1256            >>> delete("tbl").returning("*", dialect="postgres").sql()
1257            'DELETE FROM tbl RETURNING *'
1258
1259        Args:
1260            expression: the SQL code strings to parse.
1261                If an `Expression` instance is passed, it will be used as-is.
1262            dialect: the dialect used to parse the input expressions.
1263            copy: if `False`, modify this expression instance in-place.
1264            opts: other options to use to parse the input expressions.
1265
1266        Returns:
1267            Delete: the modified expression.
1268        """
1269        return _apply_builder(
1270            expression=expression,
1271            instance=self,
1272            arg="returning",
1273            prefix="RETURNING",
1274            dialect=dialect,
1275            copy=copy,
1276            into=Returning,
1277            **opts,
1278        )
1279
1280
1281class Create(DDL):
1282    arg_types = {
1283        "with": False,
1284        "this": True,
1285        "kind": True,
1286        "expression": False,
1287        "exists": False,
1288        "properties": False,
1289        "replace": False,
1290        "unique": False,
1291        "indexes": False,
1292        "no_schema_binding": False,
1293        "begin": False,
1294        "end": False,
1295        "clone": False,
1296    }
1297
1298    @property
1299    def kind(self) -> t.Optional[str]:
1300        kind = self.args.get("kind")
1301        return kind and kind.upper()
1302
1303
1304class SequenceProperties(Expression):
1305    arg_types = {
1306        "increment": False,
1307        "minvalue": False,
1308        "maxvalue": False,
1309        "cache": False,
1310        "start": False,
1311        "owned": False,
1312        "options": False,
1313    }
1314
1315
1316class TruncateTable(Expression):
1317    arg_types = {
1318        "expressions": True,
1319        "is_database": False,
1320        "exists": False,
1321        "only": False,
1322        "cluster": False,
1323        "identity": False,
1324        "option": False,
1325        "partition": False,
1326    }
1327
1328
1329# https://docs.snowflake.com/en/sql-reference/sql/create-clone
1330# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_clone_statement
1331# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_copy
1332class Clone(Expression):
1333    arg_types = {"this": True, "shallow": False, "copy": False}
1334
1335
1336class Describe(Expression):
1337    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
1338
1339
1340class Kill(Expression):
1341    arg_types = {"this": True, "kind": False}
1342
1343
1344class Pragma(Expression):
1345    pass
1346
1347
1348class Set(Expression):
1349    arg_types = {"expressions": False, "unset": False, "tag": False}
1350
1351
1352class Heredoc(Expression):
1353    arg_types = {"this": True, "tag": False}
1354
1355
1356class SetItem(Expression):
1357    arg_types = {
1358        "this": False,
1359        "expressions": False,
1360        "kind": False,
1361        "collate": False,  # MySQL SET NAMES statement
1362        "global": False,
1363    }
1364
1365
1366class Show(Expression):
1367    arg_types = {
1368        "this": True,
1369        "history": False,
1370        "terse": False,
1371        "target": False,
1372        "offset": False,
1373        "starts_with": False,
1374        "limit": False,
1375        "from": False,
1376        "like": False,
1377        "where": False,
1378        "db": False,
1379        "scope": False,
1380        "scope_kind": False,
1381        "full": False,
1382        "mutex": False,
1383        "query": False,
1384        "channel": False,
1385        "global": False,
1386        "log": False,
1387        "position": False,
1388        "types": False,
1389    }
1390
1391
1392class UserDefinedFunction(Expression):
1393    arg_types = {"this": True, "expressions": False, "wrapped": False}
1394
1395
1396class CharacterSet(Expression):
1397    arg_types = {"this": True, "default": False}
1398
1399
1400class With(Expression):
1401    arg_types = {"expressions": True, "recursive": False}
1402
1403    @property
1404    def recursive(self) -> bool:
1405        return bool(self.args.get("recursive"))
1406
1407
1408class WithinGroup(Expression):
1409    arg_types = {"this": True, "expression": False}
1410
1411
1412# clickhouse supports scalar ctes
1413# https://clickhouse.com/docs/en/sql-reference/statements/select/with
1414class CTE(DerivedTable):
1415    arg_types = {
1416        "this": True,
1417        "alias": True,
1418        "scalar": False,
1419        "materialized": False,
1420    }
1421
1422
1423class TableAlias(Expression):
1424    arg_types = {"this": False, "columns": False}
1425
1426    @property
1427    def columns(self):
1428        return self.args.get("columns") or []
1429
1430
1431class BitString(Condition):
1432    pass
1433
1434
1435class HexString(Condition):
1436    pass
1437
1438
1439class ByteString(Condition):
1440    pass
1441
1442
1443class RawString(Condition):
1444    pass
1445
1446
1447class UnicodeString(Condition):
1448    arg_types = {"this": True, "escape": False}
1449
1450
1451class Column(Condition):
1452    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1453
1454    @property
1455    def table(self) -> str:
1456        return self.text("table")
1457
1458    @property
1459    def db(self) -> str:
1460        return self.text("db")
1461
1462    @property
1463    def catalog(self) -> str:
1464        return self.text("catalog")
1465
1466    @property
1467    def output_name(self) -> str:
1468        return self.name
1469
1470    @property
1471    def parts(self) -> t.List[Identifier]:
1472        """Return the parts of a column in order catalog, db, table, name."""
1473        return [
1474            t.cast(Identifier, self.args[part])
1475            for part in ("catalog", "db", "table", "this")
1476            if self.args.get(part)
1477        ]
1478
1479    def to_dot(self) -> Dot | Identifier:
1480        """Converts the column into a dot expression."""
1481        parts = self.parts
1482        parent = self.parent
1483
1484        while parent:
1485            if isinstance(parent, Dot):
1486                parts.append(parent.expression)
1487            parent = parent.parent
1488
1489        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
1490
1491
1492class ColumnPosition(Expression):
1493    arg_types = {"this": False, "position": True}
1494
1495
1496class ColumnDef(Expression):
1497    arg_types = {
1498        "this": True,
1499        "kind": False,
1500        "constraints": False,
1501        "exists": False,
1502        "position": False,
1503    }
1504
1505    @property
1506    def constraints(self) -> t.List[ColumnConstraint]:
1507        return self.args.get("constraints") or []
1508
1509    @property
1510    def kind(self) -> t.Optional[DataType]:
1511        return self.args.get("kind")
1512
1513
1514class AlterColumn(Expression):
1515    arg_types = {
1516        "this": True,
1517        "dtype": False,
1518        "collate": False,
1519        "using": False,
1520        "default": False,
1521        "drop": False,
1522        "comment": False,
1523    }
1524
1525
1526class RenameColumn(Expression):
1527    arg_types = {"this": True, "to": True, "exists": False}
1528
1529
1530class RenameTable(Expression):
1531    pass
1532
1533
1534class SwapTable(Expression):
1535    pass
1536
1537
1538class Comment(Expression):
1539    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
1540
1541
1542class Comprehension(Expression):
1543    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
1544
1545
1546# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1547class MergeTreeTTLAction(Expression):
1548    arg_types = {
1549        "this": True,
1550        "delete": False,
1551        "recompress": False,
1552        "to_disk": False,
1553        "to_volume": False,
1554    }
1555
1556
1557# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1558class MergeTreeTTL(Expression):
1559    arg_types = {
1560        "expressions": True,
1561        "where": False,
1562        "group": False,
1563        "aggregates": False,
1564    }
1565
1566
1567# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1568class IndexConstraintOption(Expression):
1569    arg_types = {
1570        "key_block_size": False,
1571        "using": False,
1572        "parser": False,
1573        "comment": False,
1574        "visible": False,
1575        "engine_attr": False,
1576        "secondary_engine_attr": False,
1577    }
1578
1579
1580class ColumnConstraint(Expression):
1581    arg_types = {"this": False, "kind": True}
1582
1583    @property
1584    def kind(self) -> ColumnConstraintKind:
1585        return self.args["kind"]
1586
1587
1588class ColumnConstraintKind(Expression):
1589    pass
1590
1591
1592class AutoIncrementColumnConstraint(ColumnConstraintKind):
1593    pass
1594
1595
1596class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1597    arg_types = {"this": True, "expression": True}
1598
1599
1600class CaseSpecificColumnConstraint(ColumnConstraintKind):
1601    arg_types = {"not_": True}
1602
1603
1604class CharacterSetColumnConstraint(ColumnConstraintKind):
1605    arg_types = {"this": True}
1606
1607
1608class CheckColumnConstraint(ColumnConstraintKind):
1609    arg_types = {"this": True, "enforced": False}
1610
1611
1612class ClusteredColumnConstraint(ColumnConstraintKind):
1613    pass
1614
1615
1616class CollateColumnConstraint(ColumnConstraintKind):
1617    pass
1618
1619
1620class CommentColumnConstraint(ColumnConstraintKind):
1621    pass
1622
1623
1624class CompressColumnConstraint(ColumnConstraintKind):
1625    pass
1626
1627
1628class DateFormatColumnConstraint(ColumnConstraintKind):
1629    arg_types = {"this": True}
1630
1631
1632class DefaultColumnConstraint(ColumnConstraintKind):
1633    pass
1634
1635
1636class EncodeColumnConstraint(ColumnConstraintKind):
1637    pass
1638
1639
1640# https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
1641class ExcludeColumnConstraint(ColumnConstraintKind):
1642    pass
1643
1644
1645class WithOperator(Expression):
1646    arg_types = {"this": True, "op": True}
1647
1648
1649class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1650    # this: True -> ALWAYS, this: False -> BY DEFAULT
1651    arg_types = {
1652        "this": False,
1653        "expression": False,
1654        "on_null": False,
1655        "start": False,
1656        "increment": False,
1657        "minvalue": False,
1658        "maxvalue": False,
1659        "cycle": False,
1660    }
1661
1662
1663class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1664    arg_types = {"start": False, "hidden": False}
1665
1666
1667# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1668class IndexColumnConstraint(ColumnConstraintKind):
1669    arg_types = {
1670        "this": False,
1671        "schema": True,
1672        "kind": False,
1673        "index_type": False,
1674        "options": False,
1675    }
1676
1677
1678class InlineLengthColumnConstraint(ColumnConstraintKind):
1679    pass
1680
1681
1682class NonClusteredColumnConstraint(ColumnConstraintKind):
1683    pass
1684
1685
1686class NotForReplicationColumnConstraint(ColumnConstraintKind):
1687    arg_types = {}
1688
1689
1690class NotNullColumnConstraint(ColumnConstraintKind):
1691    arg_types = {"allow_null": False}
1692
1693
1694# https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
1695class OnUpdateColumnConstraint(ColumnConstraintKind):
1696    pass
1697
1698
1699# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1700class TransformColumnConstraint(ColumnConstraintKind):
1701    pass
1702
1703
1704class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1705    arg_types = {"desc": False}
1706
1707
1708class TitleColumnConstraint(ColumnConstraintKind):
1709    pass
1710
1711
1712class UniqueColumnConstraint(ColumnConstraintKind):
1713    arg_types = {"this": False, "index_type": False, "on_conflict": False}
1714
1715
1716class UppercaseColumnConstraint(ColumnConstraintKind):
1717    arg_types: t.Dict[str, t.Any] = {}
1718
1719
1720class PathColumnConstraint(ColumnConstraintKind):
1721    pass
1722
1723
1724# computed column expression
1725# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16
1726class ComputedColumnConstraint(ColumnConstraintKind):
1727    arg_types = {"this": True, "persisted": False, "not_null": False}
1728
1729
1730class Constraint(Expression):
1731    arg_types = {"this": True, "expressions": True}
1732
1733
1734class Delete(DML):
1735    arg_types = {
1736        "with": False,
1737        "this": False,
1738        "using": False,
1739        "where": False,
1740        "returning": False,
1741        "limit": False,
1742        "tables": False,  # Multiple-Table Syntax (MySQL)
1743    }
1744
1745    def delete(
1746        self,
1747        table: ExpOrStr,
1748        dialect: DialectType = None,
1749        copy: bool = True,
1750        **opts,
1751    ) -> Delete:
1752        """
1753        Create a DELETE expression or replace the table on an existing DELETE expression.
1754
1755        Example:
1756            >>> delete("tbl").sql()
1757            'DELETE FROM tbl'
1758
1759        Args:
1760            table: the table from which to delete.
1761            dialect: the dialect used to parse the input expression.
1762            copy: if `False`, modify this expression instance in-place.
1763            opts: other options to use to parse the input expressions.
1764
1765        Returns:
1766            Delete: the modified expression.
1767        """
1768        return _apply_builder(
1769            expression=table,
1770            instance=self,
1771            arg="this",
1772            dialect=dialect,
1773            into=Table,
1774            copy=copy,
1775            **opts,
1776        )
1777
1778    def where(
1779        self,
1780        *expressions: t.Optional[ExpOrStr],
1781        append: bool = True,
1782        dialect: DialectType = None,
1783        copy: bool = True,
1784        **opts,
1785    ) -> Delete:
1786        """
1787        Append to or set the WHERE expressions.
1788
1789        Example:
1790            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1791            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1792
1793        Args:
1794            *expressions: the SQL code strings to parse.
1795                If an `Expression` instance is passed, it will be used as-is.
1796                Multiple expressions are combined with an AND operator.
1797            append: if `True`, AND the new expressions to any existing expression.
1798                Otherwise, this resets the expression.
1799            dialect: the dialect used to parse the input expressions.
1800            copy: if `False`, modify this expression instance in-place.
1801            opts: other options to use to parse the input expressions.
1802
1803        Returns:
1804            Delete: the modified expression.
1805        """
1806        return _apply_conjunction_builder(
1807            *expressions,
1808            instance=self,
1809            arg="where",
1810            append=append,
1811            into=Where,
1812            dialect=dialect,
1813            copy=copy,
1814            **opts,
1815        )
1816
1817
1818class Drop(Expression):
1819    arg_types = {
1820        "this": False,
1821        "kind": False,
1822        "expressions": False,
1823        "exists": False,
1824        "temporary": False,
1825        "materialized": False,
1826        "cascade": False,
1827        "constraints": False,
1828        "purge": False,
1829    }
1830
1831
1832class Filter(Expression):
1833    arg_types = {"this": True, "expression": True}
1834
1835
1836class Check(Expression):
1837    pass
1838
1839
1840# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
1841class Connect(Expression):
1842    arg_types = {"start": False, "connect": True, "nocycle": False}
1843
1844
1845class Prior(Expression):
1846    pass
1847
1848
1849class Directory(Expression):
1850    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1851    arg_types = {"this": True, "local": False, "row_format": False}
1852
1853
1854class ForeignKey(Expression):
1855    arg_types = {
1856        "expressions": True,
1857        "reference": False,
1858        "delete": False,
1859        "update": False,
1860    }
1861
1862
1863class ColumnPrefix(Expression):
1864    arg_types = {"this": True, "expression": True}
1865
1866
1867class PrimaryKey(Expression):
1868    arg_types = {"expressions": True, "options": False}
1869
1870
1871# https://www.postgresql.org/docs/9.1/sql-selectinto.html
1872# https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_INTO.html#r_SELECT_INTO-examples
1873class Into(Expression):
1874    arg_types = {"this": True, "temporary": False, "unlogged": False}
1875
1876
1877class From(Expression):
1878    @property
1879    def name(self) -> str:
1880        return self.this.name
1881
1882    @property
1883    def alias_or_name(self) -> str:
1884        return self.this.alias_or_name
1885
1886
1887class Having(Expression):
1888    pass
1889
1890
1891class Hint(Expression):
1892    arg_types = {"expressions": True}
1893
1894
1895class JoinHint(Expression):
1896    arg_types = {"this": True, "expressions": True}
1897
1898
1899class Identifier(Expression):
1900    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1901
1902    @property
1903    def quoted(self) -> bool:
1904        return bool(self.args.get("quoted"))
1905
1906    @property
1907    def hashable_args(self) -> t.Any:
1908        return (self.this, self.quoted)
1909
1910    @property
1911    def output_name(self) -> str:
1912        return self.name
1913
1914
1915# https://www.postgresql.org/docs/current/indexes-opclass.html
1916class Opclass(Expression):
1917    arg_types = {"this": True, "expression": True}
1918
1919
1920class Index(Expression):
1921    arg_types = {
1922        "this": False,
1923        "table": False,
1924        "unique": False,
1925        "primary": False,
1926        "amp": False,  # teradata
1927        "params": False,
1928    }
1929
1930
1931class IndexParameters(Expression):
1932    arg_types = {
1933        "using": False,
1934        "include": False,
1935        "columns": False,
1936        "with_storage": False,
1937        "partition_by": False,
1938        "tablespace": False,
1939        "where": False,
1940    }
1941
1942
1943class Insert(DDL, DML):
1944    arg_types = {
1945        "hint": False,
1946        "with": False,
1947        "is_function": False,
1948        "this": True,
1949        "expression": False,
1950        "conflict": False,
1951        "returning": False,
1952        "overwrite": False,
1953        "exists": False,
1954        "partition": False,
1955        "alternative": False,
1956        "where": False,
1957        "ignore": False,
1958        "by_name": False,
1959    }
1960
1961    def with_(
1962        self,
1963        alias: ExpOrStr,
1964        as_: ExpOrStr,
1965        recursive: t.Optional[bool] = None,
1966        append: bool = True,
1967        dialect: DialectType = None,
1968        copy: bool = True,
1969        **opts,
1970    ) -> Insert:
1971        """
1972        Append to or set the common table expressions.
1973
1974        Example:
1975            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1976            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1977
1978        Args:
1979            alias: the SQL code string to parse as the table name.
1980                If an `Expression` instance is passed, this is used as-is.
1981            as_: the SQL code string to parse as the table expression.
1982                If an `Expression` instance is passed, it will be used as-is.
1983            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1984            append: if `True`, add to any existing expressions.
1985                Otherwise, this resets the expressions.
1986            dialect: the dialect used to parse the input expression.
1987            copy: if `False`, modify this expression instance in-place.
1988            opts: other options to use to parse the input expressions.
1989
1990        Returns:
1991            The modified expression.
1992        """
1993        return _apply_cte_builder(
1994            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1995        )
1996
1997
1998class OnConflict(Expression):
1999    arg_types = {
2000        "duplicate": False,
2001        "expressions": False,
2002        "action": False,
2003        "conflict_keys": False,
2004        "constraint": False,
2005    }
2006
2007
2008class Returning(Expression):
2009    arg_types = {"expressions": True, "into": False}
2010
2011
2012# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
2013class Introducer(Expression):
2014    arg_types = {"this": True, "expression": True}
2015
2016
2017# national char, like n'utf8'
2018class National(Expression):
2019    pass
2020
2021
2022class LoadData(Expression):
2023    arg_types = {
2024        "this": True,
2025        "local": False,
2026        "overwrite": False,
2027        "inpath": True,
2028        "partition": False,
2029        "input_format": False,
2030        "serde": False,
2031    }
2032
2033
2034class Partition(Expression):
2035    arg_types = {"expressions": True}
2036
2037
2038class PartitionRange(Expression):
2039    arg_types = {"this": True, "expression": True}
2040
2041
2042class Fetch(Expression):
2043    arg_types = {
2044        "direction": False,
2045        "count": False,
2046        "percent": False,
2047        "with_ties": False,
2048    }
2049
2050
2051class Group(Expression):
2052    arg_types = {
2053        "expressions": False,
2054        "grouping_sets": False,
2055        "cube": False,
2056        "rollup": False,
2057        "totals": False,
2058        "all": False,
2059    }
2060
2061
2062class Lambda(Expression):
2063    arg_types = {"this": True, "expressions": True}
2064
2065
2066class Limit(Expression):
2067    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
2068
2069
2070class Literal(Condition):
2071    arg_types = {"this": True, "is_string": True}
2072
2073    @property
2074    def hashable_args(self) -> t.Any:
2075        return (self.this, self.args.get("is_string"))
2076
2077    @classmethod
2078    def number(cls, number) -> Literal:
2079        return cls(this=str(number), is_string=False)
2080
2081    @classmethod
2082    def string(cls, string) -> Literal:
2083        return cls(this=str(string), is_string=True)
2084
2085    @property
2086    def output_name(self) -> str:
2087        return self.name
2088
2089
2090class Join(Expression):
2091    arg_types = {
2092        "this": True,
2093        "on": False,
2094        "side": False,
2095        "kind": False,
2096        "using": False,
2097        "method": False,
2098        "global": False,
2099        "hint": False,
2100    }
2101
2102    @property
2103    def method(self) -> str:
2104        return self.text("method").upper()
2105
2106    @property
2107    def kind(self) -> str:
2108        return self.text("kind").upper()
2109
2110    @property
2111    def side(self) -> str:
2112        return self.text("side").upper()
2113
2114    @property
2115    def hint(self) -> str:
2116        return self.text("hint").upper()
2117
2118    @property
2119    def alias_or_name(self) -> str:
2120        return self.this.alias_or_name
2121
2122    def on(
2123        self,
2124        *expressions: t.Optional[ExpOrStr],
2125        append: bool = True,
2126        dialect: DialectType = None,
2127        copy: bool = True,
2128        **opts,
2129    ) -> Join:
2130        """
2131        Append to or set the ON expressions.
2132
2133        Example:
2134            >>> import sqlglot
2135            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2136            'JOIN x ON y = 1'
2137
2138        Args:
2139            *expressions: the SQL code strings to parse.
2140                If an `Expression` instance is passed, it will be used as-is.
2141                Multiple expressions are combined with an AND operator.
2142            append: if `True`, AND the new expressions to any existing expression.
2143                Otherwise, this resets the expression.
2144            dialect: the dialect used to parse the input expressions.
2145            copy: if `False`, modify this expression instance in-place.
2146            opts: other options to use to parse the input expressions.
2147
2148        Returns:
2149            The modified Join expression.
2150        """
2151        join = _apply_conjunction_builder(
2152            *expressions,
2153            instance=self,
2154            arg="on",
2155            append=append,
2156            dialect=dialect,
2157            copy=copy,
2158            **opts,
2159        )
2160
2161        if join.kind == "CROSS":
2162            join.set("kind", None)
2163
2164        return join
2165
2166    def using(
2167        self,
2168        *expressions: t.Optional[ExpOrStr],
2169        append: bool = True,
2170        dialect: DialectType = None,
2171        copy: bool = True,
2172        **opts,
2173    ) -> Join:
2174        """
2175        Append to or set the USING expressions.
2176
2177        Example:
2178            >>> import sqlglot
2179            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2180            'JOIN x USING (foo, bla)'
2181
2182        Args:
2183            *expressions: the SQL code strings to parse.
2184                If an `Expression` instance is passed, it will be used as-is.
2185            append: if `True`, concatenate the new expressions to the existing "using" list.
2186                Otherwise, this resets the expression.
2187            dialect: the dialect used to parse the input expressions.
2188            copy: if `False`, modify this expression instance in-place.
2189            opts: other options to use to parse the input expressions.
2190
2191        Returns:
2192            The modified Join expression.
2193        """
2194        join = _apply_list_builder(
2195            *expressions,
2196            instance=self,
2197            arg="using",
2198            append=append,
2199            dialect=dialect,
2200            copy=copy,
2201            **opts,
2202        )
2203
2204        if join.kind == "CROSS":
2205            join.set("kind", None)
2206
2207        return join
2208
2209
2210class Lateral(UDTF):
2211    arg_types = {
2212        "this": True,
2213        "view": False,
2214        "outer": False,
2215        "alias": False,
2216        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2217    }
2218
2219
2220class MatchRecognize(Expression):
2221    arg_types = {
2222        "partition_by": False,
2223        "order": False,
2224        "measures": False,
2225        "rows": False,
2226        "after": False,
2227        "pattern": False,
2228        "define": False,
2229        "alias": False,
2230    }
2231
2232
2233# Clickhouse FROM FINAL modifier
2234# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2235class Final(Expression):
2236    pass
2237
2238
2239class Offset(Expression):
2240    arg_types = {"this": False, "expression": True, "expressions": False}
2241
2242
2243class Order(Expression):
2244    arg_types = {
2245        "this": False,
2246        "expressions": True,
2247        "interpolate": False,
2248        "siblings": False,
2249    }
2250
2251
2252# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2253class WithFill(Expression):
2254    arg_types = {"from": False, "to": False, "step": False}
2255
2256
2257# hive specific sorts
2258# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2259class Cluster(Order):
2260    pass
2261
2262
2263class Distribute(Order):
2264    pass
2265
2266
2267class Sort(Order):
2268    pass
2269
2270
2271class Ordered(Expression):
2272    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2273
2274
2275class Property(Expression):
2276    arg_types = {"this": True, "value": True}
2277
2278
2279class AlgorithmProperty(Property):
2280    arg_types = {"this": True}
2281
2282
2283class AutoIncrementProperty(Property):
2284    arg_types = {"this": True}
2285
2286
2287# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2288class AutoRefreshProperty(Property):
2289    arg_types = {"this": True}
2290
2291
2292class BackupProperty(Property):
2293    arg_types = {"this": True}
2294
2295
2296class BlockCompressionProperty(Property):
2297    arg_types = {
2298        "autotemp": False,
2299        "always": False,
2300        "default": False,
2301        "manual": False,
2302        "never": False,
2303    }
2304
2305
2306class CharacterSetProperty(Property):
2307    arg_types = {"this": True, "default": True}
2308
2309
2310class ChecksumProperty(Property):
2311    arg_types = {"on": False, "default": False}
2312
2313
2314class CollateProperty(Property):
2315    arg_types = {"this": True, "default": False}
2316
2317
2318class CopyGrantsProperty(Property):
2319    arg_types = {}
2320
2321
2322class DataBlocksizeProperty(Property):
2323    arg_types = {
2324        "size": False,
2325        "units": False,
2326        "minimum": False,
2327        "maximum": False,
2328        "default": False,
2329    }
2330
2331
2332class DefinerProperty(Property):
2333    arg_types = {"this": True}
2334
2335
2336class DistKeyProperty(Property):
2337    arg_types = {"this": True}
2338
2339
2340class DistStyleProperty(Property):
2341    arg_types = {"this": True}
2342
2343
2344class EngineProperty(Property):
2345    arg_types = {"this": True}
2346
2347
2348class HeapProperty(Property):
2349    arg_types = {}
2350
2351
2352class ToTableProperty(Property):
2353    arg_types = {"this": True}
2354
2355
2356class ExecuteAsProperty(Property):
2357    arg_types = {"this": True}
2358
2359
2360class ExternalProperty(Property):
2361    arg_types = {"this": False}
2362
2363
2364class FallbackProperty(Property):
2365    arg_types = {"no": True, "protection": False}
2366
2367
2368class FileFormatProperty(Property):
2369    arg_types = {"this": True}
2370
2371
2372class FreespaceProperty(Property):
2373    arg_types = {"this": True, "percent": False}
2374
2375
2376class GlobalProperty(Property):
2377    arg_types = {}
2378
2379
2380class IcebergProperty(Property):
2381    arg_types = {}
2382
2383
2384class InheritsProperty(Property):
2385    arg_types = {"expressions": True}
2386
2387
2388class InputModelProperty(Property):
2389    arg_types = {"this": True}
2390
2391
2392class OutputModelProperty(Property):
2393    arg_types = {"this": True}
2394
2395
2396class IsolatedLoadingProperty(Property):
2397    arg_types = {"no": False, "concurrent": False, "target": False}
2398
2399
2400class JournalProperty(Property):
2401    arg_types = {
2402        "no": False,
2403        "dual": False,
2404        "before": False,
2405        "local": False,
2406        "after": False,
2407    }
2408
2409
2410class LanguageProperty(Property):
2411    arg_types = {"this": True}
2412
2413
2414# spark ddl
2415class ClusteredByProperty(Property):
2416    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2417
2418
2419class DictProperty(Property):
2420    arg_types = {"this": True, "kind": True, "settings": False}
2421
2422
2423class DictSubProperty(Property):
2424    pass
2425
2426
2427class DictRange(Property):
2428    arg_types = {"this": True, "min": True, "max": True}
2429
2430
2431# Clickhouse CREATE ... ON CLUSTER modifier
2432# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2433class OnCluster(Property):
2434    arg_types = {"this": True}
2435
2436
2437class LikeProperty(Property):
2438    arg_types = {"this": True, "expressions": False}
2439
2440
2441class LocationProperty(Property):
2442    arg_types = {"this": True}
2443
2444
2445class LockProperty(Property):
2446    arg_types = {"this": True}
2447
2448
2449class LockingProperty(Property):
2450    arg_types = {
2451        "this": False,
2452        "kind": True,
2453        "for_or_in": False,
2454        "lock_type": True,
2455        "override": False,
2456    }
2457
2458
2459class LogProperty(Property):
2460    arg_types = {"no": True}
2461
2462
2463class MaterializedProperty(Property):
2464    arg_types = {"this": False}
2465
2466
2467class MergeBlockRatioProperty(Property):
2468    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2469
2470
2471class NoPrimaryIndexProperty(Property):
2472    arg_types = {}
2473
2474
2475class OnProperty(Property):
2476    arg_types = {"this": True}
2477
2478
2479class OnCommitProperty(Property):
2480    arg_types = {"delete": False}
2481
2482
2483class PartitionedByProperty(Property):
2484    arg_types = {"this": True}
2485
2486
2487# https://www.postgresql.org/docs/current/sql-createtable.html
2488class PartitionBoundSpec(Expression):
2489    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2490    arg_types = {
2491        "this": False,
2492        "expression": False,
2493        "from_expressions": False,
2494        "to_expressions": False,
2495    }
2496
2497
2498class PartitionedOfProperty(Property):
2499    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2500    arg_types = {"this": True, "expression": True}
2501
2502
2503class RemoteWithConnectionModelProperty(Property):
2504    arg_types = {"this": True}
2505
2506
2507class ReturnsProperty(Property):
2508    arg_types = {"this": True, "is_table": False, "table": False}
2509
2510
2511class RowFormatProperty(Property):
2512    arg_types = {"this": True}
2513
2514
2515class RowFormatDelimitedProperty(Property):
2516    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2517    arg_types = {
2518        "fields": False,
2519        "escaped": False,
2520        "collection_items": False,
2521        "map_keys": False,
2522        "lines": False,
2523        "null": False,
2524        "serde": False,
2525    }
2526
2527
2528class RowFormatSerdeProperty(Property):
2529    arg_types = {"this": True, "serde_properties": False}
2530
2531
2532# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
2533class QueryTransform(Expression):
2534    arg_types = {
2535        "expressions": True,
2536        "command_script": True,
2537        "schema": False,
2538        "row_format_before": False,
2539        "record_writer": False,
2540        "row_format_after": False,
2541        "record_reader": False,
2542    }
2543
2544
2545class SampleProperty(Property):
2546    arg_types = {"this": True}
2547
2548
2549class SchemaCommentProperty(Property):
2550    arg_types = {"this": True}
2551
2552
2553class SerdeProperties(Property):
2554    arg_types = {"expressions": True}
2555
2556
2557class SetProperty(Property):
2558    arg_types = {"multi": True}
2559
2560
2561class SharingProperty(Property):
2562    arg_types = {"this": False}
2563
2564
2565class SetConfigProperty(Property):
2566    arg_types = {"this": True}
2567
2568
2569class SettingsProperty(Property):
2570    arg_types = {"expressions": True}
2571
2572
2573class SortKeyProperty(Property):
2574    arg_types = {"this": True, "compound": False}
2575
2576
2577class SqlReadWriteProperty(Property):
2578    arg_types = {"this": True}
2579
2580
2581class SqlSecurityProperty(Property):
2582    arg_types = {"definer": True}
2583
2584
2585class StabilityProperty(Property):
2586    arg_types = {"this": True}
2587
2588
2589class TemporaryProperty(Property):
2590    arg_types = {"this": False}
2591
2592
2593class TransformModelProperty(Property):
2594    arg_types = {"expressions": True}
2595
2596
2597class TransientProperty(Property):
2598    arg_types = {"this": False}
2599
2600
2601class UnloggedProperty(Property):
2602    arg_types = {}
2603
2604
2605# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
2606class ViewAttributeProperty(Property):
2607    arg_types = {"this": True}
2608
2609
2610class VolatileProperty(Property):
2611    arg_types = {"this": False}
2612
2613
2614class WithDataProperty(Property):
2615    arg_types = {"no": True, "statistics": False}
2616
2617
2618class WithJournalTableProperty(Property):
2619    arg_types = {"this": True}
2620
2621
2622class WithSystemVersioningProperty(Property):
2623    # this -> history table name, expression -> data consistency check
2624    arg_types = {"this": False, "expression": False}
2625
2626
2627class Properties(Expression):
2628    arg_types = {"expressions": True}
2629
2630    NAME_TO_PROPERTY = {
2631        "ALGORITHM": AlgorithmProperty,
2632        "AUTO_INCREMENT": AutoIncrementProperty,
2633        "CHARACTER SET": CharacterSetProperty,
2634        "CLUSTERED_BY": ClusteredByProperty,
2635        "COLLATE": CollateProperty,
2636        "COMMENT": SchemaCommentProperty,
2637        "DEFINER": DefinerProperty,
2638        "DISTKEY": DistKeyProperty,
2639        "DISTSTYLE": DistStyleProperty,
2640        "ENGINE": EngineProperty,
2641        "EXECUTE AS": ExecuteAsProperty,
2642        "FORMAT": FileFormatProperty,
2643        "LANGUAGE": LanguageProperty,
2644        "LOCATION": LocationProperty,
2645        "LOCK": LockProperty,
2646        "PARTITIONED_BY": PartitionedByProperty,
2647        "RETURNS": ReturnsProperty,
2648        "ROW_FORMAT": RowFormatProperty,
2649        "SORTKEY": SortKeyProperty,
2650    }
2651
2652    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2653
2654    # CREATE property locations
2655    # Form: schema specified
2656    #   create [POST_CREATE]
2657    #     table a [POST_NAME]
2658    #     (b int) [POST_SCHEMA]
2659    #     with ([POST_WITH])
2660    #     index (b) [POST_INDEX]
2661    #
2662    # Form: alias selection
2663    #   create [POST_CREATE]
2664    #     table a [POST_NAME]
2665    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2666    #     index (c) [POST_INDEX]
2667    class Location(AutoName):
2668        POST_CREATE = auto()
2669        POST_NAME = auto()
2670        POST_SCHEMA = auto()
2671        POST_WITH = auto()
2672        POST_ALIAS = auto()
2673        POST_EXPRESSION = auto()
2674        POST_INDEX = auto()
2675        UNSUPPORTED = auto()
2676
2677    @classmethod
2678    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2679        expressions = []
2680        for key, value in properties_dict.items():
2681            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2682            if property_cls:
2683                expressions.append(property_cls(this=convert(value)))
2684            else:
2685                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2686
2687        return cls(expressions=expressions)
2688
2689
2690class Qualify(Expression):
2691    pass
2692
2693
2694class InputOutputFormat(Expression):
2695    arg_types = {"input_format": False, "output_format": False}
2696
2697
2698# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
2699class Return(Expression):
2700    pass
2701
2702
2703class Reference(Expression):
2704    arg_types = {"this": True, "expressions": False, "options": False}
2705
2706
2707class Tuple(Expression):
2708    arg_types = {"expressions": False}
2709
2710    def isin(
2711        self,
2712        *expressions: t.Any,
2713        query: t.Optional[ExpOrStr] = None,
2714        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2715        copy: bool = True,
2716        **opts,
2717    ) -> In:
2718        return In(
2719            this=maybe_copy(self, copy),
2720            expressions=[convert(e, copy=copy) for e in expressions],
2721            query=maybe_parse(query, copy=copy, **opts) if query else None,
2722            unnest=(
2723                Unnest(
2724                    expressions=[
2725                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2726                        for e in ensure_list(unnest)
2727                    ]
2728                )
2729                if unnest
2730                else None
2731            ),
2732        )
2733
2734
2735QUERY_MODIFIERS = {
2736    "match": False,
2737    "laterals": False,
2738    "joins": False,
2739    "connect": False,
2740    "pivots": False,
2741    "prewhere": False,
2742    "where": False,
2743    "group": False,
2744    "having": False,
2745    "qualify": False,
2746    "windows": False,
2747    "distribute": False,
2748    "sort": False,
2749    "cluster": False,
2750    "order": False,
2751    "limit": False,
2752    "offset": False,
2753    "locks": False,
2754    "sample": False,
2755    "settings": False,
2756    "format": False,
2757    "options": False,
2758}
2759
2760
2761# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
2762# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
2763class QueryOption(Expression):
2764    arg_types = {"this": True, "expression": False}
2765
2766
2767# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
2768class WithTableHint(Expression):
2769    arg_types = {"expressions": True}
2770
2771
2772# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
2773class IndexTableHint(Expression):
2774    arg_types = {"this": True, "expressions": False, "target": False}
2775
2776
2777# https://docs.snowflake.com/en/sql-reference/constructs/at-before
2778class HistoricalData(Expression):
2779    arg_types = {"this": True, "kind": True, "expression": True}
2780
2781
2782class Table(Expression):
2783    arg_types = {
2784        "this": False,
2785        "alias": False,
2786        "db": False,
2787        "catalog": False,
2788        "laterals": False,
2789        "joins": False,
2790        "pivots": False,
2791        "hints": False,
2792        "system_time": False,
2793        "version": False,
2794        "format": False,
2795        "pattern": False,
2796        "ordinality": False,
2797        "when": False,
2798        "only": False,
2799    }
2800
2801    @property
2802    def name(self) -> str:
2803        if isinstance(self.this, Func):
2804            return ""
2805        return self.this.name
2806
2807    @property
2808    def db(self) -> str:
2809        return self.text("db")
2810
2811    @property
2812    def catalog(self) -> str:
2813        return self.text("catalog")
2814
2815    @property
2816    def selects(self) -> t.List[Expression]:
2817        return []
2818
2819    @property
2820    def named_selects(self) -> t.List[str]:
2821        return []
2822
2823    @property
2824    def parts(self) -> t.List[Expression]:
2825        """Return the parts of a table in order catalog, db, table."""
2826        parts: t.List[Expression] = []
2827
2828        for arg in ("catalog", "db", "this"):
2829            part = self.args.get(arg)
2830
2831            if isinstance(part, Dot):
2832                parts.extend(part.flatten())
2833            elif isinstance(part, Expression):
2834                parts.append(part)
2835
2836        return parts
2837
2838    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2839        parts = self.parts
2840        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2841        alias = self.args.get("alias")
2842        if alias:
2843            col = alias_(col, alias.this, copy=copy)
2844        return col
2845
2846
2847class Union(Query):
2848    arg_types = {
2849        "with": False,
2850        "this": True,
2851        "expression": True,
2852        "distinct": False,
2853        "by_name": False,
2854        **QUERY_MODIFIERS,
2855    }
2856
2857    def select(
2858        self,
2859        *expressions: t.Optional[ExpOrStr],
2860        append: bool = True,
2861        dialect: DialectType = None,
2862        copy: bool = True,
2863        **opts,
2864    ) -> Union:
2865        this = maybe_copy(self, copy)
2866        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2867        this.expression.unnest().select(
2868            *expressions, append=append, dialect=dialect, copy=False, **opts
2869        )
2870        return this
2871
2872    @property
2873    def named_selects(self) -> t.List[str]:
2874        return self.this.unnest().named_selects
2875
2876    @property
2877    def is_star(self) -> bool:
2878        return self.this.is_star or self.expression.is_star
2879
2880    @property
2881    def selects(self) -> t.List[Expression]:
2882        return self.this.unnest().selects
2883
2884    @property
2885    def left(self) -> Expression:
2886        return self.this
2887
2888    @property
2889    def right(self) -> Expression:
2890        return self.expression
2891
2892
2893class Except(Union):
2894    pass
2895
2896
2897class Intersect(Union):
2898    pass
2899
2900
2901class Unnest(UDTF):
2902    arg_types = {
2903        "expressions": True,
2904        "alias": False,
2905        "offset": False,
2906    }
2907
2908    @property
2909    def selects(self) -> t.List[Expression]:
2910        columns = super().selects
2911        offset = self.args.get("offset")
2912        if offset:
2913            columns = columns + [to_identifier("offset") if offset is True else offset]
2914        return columns
2915
2916
2917class Update(Expression):
2918    arg_types = {
2919        "with": False,
2920        "this": False,
2921        "expressions": True,
2922        "from": False,
2923        "where": False,
2924        "returning": False,
2925        "order": False,
2926        "limit": False,
2927    }
2928
2929
2930class Values(UDTF):
2931    arg_types = {"expressions": True, "alias": False}
2932
2933
2934class Var(Expression):
2935    pass
2936
2937
2938class Version(Expression):
2939    """
2940    Time travel, iceberg, bigquery etc
2941    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2942    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2943    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2944    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2945    this is either TIMESTAMP or VERSION
2946    kind is ("AS OF", "BETWEEN")
2947    """
2948
2949    arg_types = {"this": True, "kind": True, "expression": False}
2950
2951
2952class Schema(Expression):
2953    arg_types = {"this": False, "expressions": False}
2954
2955
2956# https://dev.mysql.com/doc/refman/8.0/en/select.html
2957# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
2958class Lock(Expression):
2959    arg_types = {"update": True, "expressions": False, "wait": False}
2960
2961
2962class Select(Query):
2963    arg_types = {
2964        "with": False,
2965        "kind": False,
2966        "expressions": False,
2967        "hint": False,
2968        "distinct": False,
2969        "into": False,
2970        "from": False,
2971        **QUERY_MODIFIERS,
2972    }
2973
2974    def from_(
2975        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2976    ) -> Select:
2977        """
2978        Set the FROM expression.
2979
2980        Example:
2981            >>> Select().from_("tbl").select("x").sql()
2982            'SELECT x FROM tbl'
2983
2984        Args:
2985            expression : the SQL code strings to parse.
2986                If a `From` instance is passed, this is used as-is.
2987                If another `Expression` instance is passed, it will be wrapped in a `From`.
2988            dialect: the dialect used to parse the input expression.
2989            copy: if `False`, modify this expression instance in-place.
2990            opts: other options to use to parse the input expressions.
2991
2992        Returns:
2993            The modified Select expression.
2994        """
2995        return _apply_builder(
2996            expression=expression,
2997            instance=self,
2998            arg="from",
2999            into=From,
3000            prefix="FROM",
3001            dialect=dialect,
3002            copy=copy,
3003            **opts,
3004        )
3005
3006    def group_by(
3007        self,
3008        *expressions: t.Optional[ExpOrStr],
3009        append: bool = True,
3010        dialect: DialectType = None,
3011        copy: bool = True,
3012        **opts,
3013    ) -> Select:
3014        """
3015        Set the GROUP BY expression.
3016
3017        Example:
3018            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3019            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3020
3021        Args:
3022            *expressions: the SQL code strings to parse.
3023                If a `Group` instance is passed, this is used as-is.
3024                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3025                If nothing is passed in then a group by is not applied to the expression
3026            append: if `True`, add to any existing expressions.
3027                Otherwise, this flattens all the `Group` expression into a single expression.
3028            dialect: the dialect used to parse the input expression.
3029            copy: if `False`, modify this expression instance in-place.
3030            opts: other options to use to parse the input expressions.
3031
3032        Returns:
3033            The modified Select expression.
3034        """
3035        if not expressions:
3036            return self if not copy else self.copy()
3037
3038        return _apply_child_list_builder(
3039            *expressions,
3040            instance=self,
3041            arg="group",
3042            append=append,
3043            copy=copy,
3044            prefix="GROUP BY",
3045            into=Group,
3046            dialect=dialect,
3047            **opts,
3048        )
3049
3050    def order_by(
3051        self,
3052        *expressions: t.Optional[ExpOrStr],
3053        append: bool = True,
3054        dialect: DialectType = None,
3055        copy: bool = True,
3056        **opts,
3057    ) -> Select:
3058        """
3059        Set the ORDER BY expression.
3060
3061        Example:
3062            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
3063            'SELECT x FROM tbl ORDER BY x DESC'
3064
3065        Args:
3066            *expressions: the SQL code strings to parse.
3067                If a `Group` instance is passed, this is used as-is.
3068                If another `Expression` instance is passed, it will be wrapped in a `Order`.
3069            append: if `True`, add to any existing expressions.
3070                Otherwise, this flattens all the `Order` expression into a single expression.
3071            dialect: the dialect used to parse the input expression.
3072            copy: if `False`, modify this expression instance in-place.
3073            opts: other options to use to parse the input expressions.
3074
3075        Returns:
3076            The modified Select expression.
3077        """
3078        return _apply_child_list_builder(
3079            *expressions,
3080            instance=self,
3081            arg="order",
3082            append=append,
3083            copy=copy,
3084            prefix="ORDER BY",
3085            into=Order,
3086            dialect=dialect,
3087            **opts,
3088        )
3089
3090    def sort_by(
3091        self,
3092        *expressions: t.Optional[ExpOrStr],
3093        append: bool = True,
3094        dialect: DialectType = None,
3095        copy: bool = True,
3096        **opts,
3097    ) -> Select:
3098        """
3099        Set the SORT BY expression.
3100
3101        Example:
3102            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3103            'SELECT x FROM tbl SORT BY x DESC'
3104
3105        Args:
3106            *expressions: the SQL code strings to parse.
3107                If a `Group` instance is passed, this is used as-is.
3108                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3109            append: if `True`, add to any existing expressions.
3110                Otherwise, this flattens all the `Order` expression into a single expression.
3111            dialect: the dialect used to parse the input expression.
3112            copy: if `False`, modify this expression instance in-place.
3113            opts: other options to use to parse the input expressions.
3114
3115        Returns:
3116            The modified Select expression.
3117        """
3118        return _apply_child_list_builder(
3119            *expressions,
3120            instance=self,
3121            arg="sort",
3122            append=append,
3123            copy=copy,
3124            prefix="SORT BY",
3125            into=Sort,
3126            dialect=dialect,
3127            **opts,
3128        )
3129
3130    def cluster_by(
3131        self,
3132        *expressions: t.Optional[ExpOrStr],
3133        append: bool = True,
3134        dialect: DialectType = None,
3135        copy: bool = True,
3136        **opts,
3137    ) -> Select:
3138        """
3139        Set the CLUSTER BY expression.
3140
3141        Example:
3142            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3143            'SELECT x FROM tbl CLUSTER BY x DESC'
3144
3145        Args:
3146            *expressions: the SQL code strings to parse.
3147                If a `Group` instance is passed, this is used as-is.
3148                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3149            append: if `True`, add to any existing expressions.
3150                Otherwise, this flattens all the `Order` expression into a single expression.
3151            dialect: the dialect used to parse the input expression.
3152            copy: if `False`, modify this expression instance in-place.
3153            opts: other options to use to parse the input expressions.
3154
3155        Returns:
3156            The modified Select expression.
3157        """
3158        return _apply_child_list_builder(
3159            *expressions,
3160            instance=self,
3161            arg="cluster",
3162            append=append,
3163            copy=copy,
3164            prefix="CLUSTER BY",
3165            into=Cluster,
3166            dialect=dialect,
3167            **opts,
3168        )
3169
3170    def limit(
3171        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3172    ) -> Select:
3173        return _apply_builder(
3174            expression=expression,
3175            instance=self,
3176            arg="limit",
3177            into=Limit,
3178            prefix="LIMIT",
3179            dialect=dialect,
3180            copy=copy,
3181            into_arg="expression",
3182            **opts,
3183        )
3184
3185    def offset(
3186        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3187    ) -> Select:
3188        """
3189        Set the OFFSET expression.
3190
3191        Example:
3192            >>> Select().from_("tbl").select("x").offset(10).sql()
3193            'SELECT x FROM tbl OFFSET 10'
3194
3195        Args:
3196            expression: the SQL code string to parse.
3197                This can also be an integer.
3198                If a `Offset` instance is passed, this is used as-is.
3199                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3200            dialect: the dialect used to parse the input expression.
3201            copy: if `False`, modify this expression instance in-place.
3202            opts: other options to use to parse the input expressions.
3203
3204        Returns:
3205            The modified Select expression.
3206        """
3207        return _apply_builder(
3208            expression=expression,
3209            instance=self,
3210            arg="offset",
3211            into=Offset,
3212            prefix="OFFSET",
3213            dialect=dialect,
3214            copy=copy,
3215            into_arg="expression",
3216            **opts,
3217        )
3218
3219    def select(
3220        self,
3221        *expressions: t.Optional[ExpOrStr],
3222        append: bool = True,
3223        dialect: DialectType = None,
3224        copy: bool = True,
3225        **opts,
3226    ) -> Select:
3227        return _apply_list_builder(
3228            *expressions,
3229            instance=self,
3230            arg="expressions",
3231            append=append,
3232            dialect=dialect,
3233            into=Expression,
3234            copy=copy,
3235            **opts,
3236        )
3237
3238    def lateral(
3239        self,
3240        *expressions: t.Optional[ExpOrStr],
3241        append: bool = True,
3242        dialect: DialectType = None,
3243        copy: bool = True,
3244        **opts,
3245    ) -> Select:
3246        """
3247        Append to or set the LATERAL expressions.
3248
3249        Example:
3250            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3251            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3252
3253        Args:
3254            *expressions: the SQL code strings to parse.
3255                If an `Expression` instance is passed, it will be used as-is.
3256            append: if `True`, add to any existing expressions.
3257                Otherwise, this resets the expressions.
3258            dialect: the dialect used to parse the input expressions.
3259            copy: if `False`, modify this expression instance in-place.
3260            opts: other options to use to parse the input expressions.
3261
3262        Returns:
3263            The modified Select expression.
3264        """
3265        return _apply_list_builder(
3266            *expressions,
3267            instance=self,
3268            arg="laterals",
3269            append=append,
3270            into=Lateral,
3271            prefix="LATERAL VIEW",
3272            dialect=dialect,
3273            copy=copy,
3274            **opts,
3275        )
3276
3277    def join(
3278        self,
3279        expression: ExpOrStr,
3280        on: t.Optional[ExpOrStr] = None,
3281        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3282        append: bool = True,
3283        join_type: t.Optional[str] = None,
3284        join_alias: t.Optional[Identifier | str] = None,
3285        dialect: DialectType = None,
3286        copy: bool = True,
3287        **opts,
3288    ) -> Select:
3289        """
3290        Append to or set the JOIN expressions.
3291
3292        Example:
3293            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3294            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3295
3296            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3297            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3298
3299            Use `join_type` to change the type of join:
3300
3301            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3302            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3303
3304        Args:
3305            expression: the SQL code string to parse.
3306                If an `Expression` instance is passed, it will be used as-is.
3307            on: optionally specify the join "on" criteria as a SQL string.
3308                If an `Expression` instance is passed, it will be used as-is.
3309            using: optionally specify the join "using" criteria as a SQL string.
3310                If an `Expression` instance is passed, it will be used as-is.
3311            append: if `True`, add to any existing expressions.
3312                Otherwise, this resets the expressions.
3313            join_type: if set, alter the parsed join type.
3314            join_alias: an optional alias for the joined source.
3315            dialect: the dialect used to parse the input expressions.
3316            copy: if `False`, modify this expression instance in-place.
3317            opts: other options to use to parse the input expressions.
3318
3319        Returns:
3320            Select: the modified expression.
3321        """
3322        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3323
3324        try:
3325            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3326        except ParseError:
3327            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3328
3329        join = expression if isinstance(expression, Join) else Join(this=expression)
3330
3331        if isinstance(join.this, Select):
3332            join.this.replace(join.this.subquery())
3333
3334        if join_type:
3335            method: t.Optional[Token]
3336            side: t.Optional[Token]
3337            kind: t.Optional[Token]
3338
3339            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3340
3341            if method:
3342                join.set("method", method.text)
3343            if side:
3344                join.set("side", side.text)
3345            if kind:
3346                join.set("kind", kind.text)
3347
3348        if on:
3349            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3350            join.set("on", on)
3351
3352        if using:
3353            join = _apply_list_builder(
3354                *ensure_list(using),
3355                instance=join,
3356                arg="using",
3357                append=append,
3358                copy=copy,
3359                into=Identifier,
3360                **opts,
3361            )
3362
3363        if join_alias:
3364            join.set("this", alias_(join.this, join_alias, table=True))
3365
3366        return _apply_list_builder(
3367            join,
3368            instance=self,
3369            arg="joins",
3370            append=append,
3371            copy=copy,
3372            **opts,
3373        )
3374
3375    def where(
3376        self,
3377        *expressions: t.Optional[ExpOrStr],
3378        append: bool = True,
3379        dialect: DialectType = None,
3380        copy: bool = True,
3381        **opts,
3382    ) -> Select:
3383        """
3384        Append to or set the WHERE expressions.
3385
3386        Example:
3387            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3388            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3389
3390        Args:
3391            *expressions: the SQL code strings to parse.
3392                If an `Expression` instance is passed, it will be used as-is.
3393                Multiple expressions are combined with an AND operator.
3394            append: if `True`, AND the new expressions to any existing expression.
3395                Otherwise, this resets the expression.
3396            dialect: the dialect used to parse the input expressions.
3397            copy: if `False`, modify this expression instance in-place.
3398            opts: other options to use to parse the input expressions.
3399
3400        Returns:
3401            Select: the modified expression.
3402        """
3403        return _apply_conjunction_builder(
3404            *expressions,
3405            instance=self,
3406            arg="where",
3407            append=append,
3408            into=Where,
3409            dialect=dialect,
3410            copy=copy,
3411            **opts,
3412        )
3413
3414    def having(
3415        self,
3416        *expressions: t.Optional[ExpOrStr],
3417        append: bool = True,
3418        dialect: DialectType = None,
3419        copy: bool = True,
3420        **opts,
3421    ) -> Select:
3422        """
3423        Append to or set the HAVING expressions.
3424
3425        Example:
3426            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3427            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3428
3429        Args:
3430            *expressions: the SQL code strings to parse.
3431                If an `Expression` instance is passed, it will be used as-is.
3432                Multiple expressions are combined with an AND operator.
3433            append: if `True`, AND the new expressions to any existing expression.
3434                Otherwise, this resets the expression.
3435            dialect: the dialect used to parse the input expressions.
3436            copy: if `False`, modify this expression instance in-place.
3437            opts: other options to use to parse the input expressions.
3438
3439        Returns:
3440            The modified Select expression.
3441        """
3442        return _apply_conjunction_builder(
3443            *expressions,
3444            instance=self,
3445            arg="having",
3446            append=append,
3447            into=Having,
3448            dialect=dialect,
3449            copy=copy,
3450            **opts,
3451        )
3452
3453    def window(
3454        self,
3455        *expressions: t.Optional[ExpOrStr],
3456        append: bool = True,
3457        dialect: DialectType = None,
3458        copy: bool = True,
3459        **opts,
3460    ) -> Select:
3461        return _apply_list_builder(
3462            *expressions,
3463            instance=self,
3464            arg="windows",
3465            append=append,
3466            into=Window,
3467            dialect=dialect,
3468            copy=copy,
3469            **opts,
3470        )
3471
3472    def qualify(
3473        self,
3474        *expressions: t.Optional[ExpOrStr],
3475        append: bool = True,
3476        dialect: DialectType = None,
3477        copy: bool = True,
3478        **opts,
3479    ) -> Select:
3480        return _apply_conjunction_builder(
3481            *expressions,
3482            instance=self,
3483            arg="qualify",
3484            append=append,
3485            into=Qualify,
3486            dialect=dialect,
3487            copy=copy,
3488            **opts,
3489        )
3490
3491    def distinct(
3492        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3493    ) -> Select:
3494        """
3495        Set the OFFSET expression.
3496
3497        Example:
3498            >>> Select().from_("tbl").select("x").distinct().sql()
3499            'SELECT DISTINCT x FROM tbl'
3500
3501        Args:
3502            ons: the expressions to distinct on
3503            distinct: whether the Select should be distinct
3504            copy: if `False`, modify this expression instance in-place.
3505
3506        Returns:
3507            Select: the modified expression.
3508        """
3509        instance = maybe_copy(self, copy)
3510        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3511        instance.set("distinct", Distinct(on=on) if distinct else None)
3512        return instance
3513
3514    def ctas(
3515        self,
3516        table: ExpOrStr,
3517        properties: t.Optional[t.Dict] = None,
3518        dialect: DialectType = None,
3519        copy: bool = True,
3520        **opts,
3521    ) -> Create:
3522        """
3523        Convert this expression to a CREATE TABLE AS statement.
3524
3525        Example:
3526            >>> Select().select("*").from_("tbl").ctas("x").sql()
3527            'CREATE TABLE x AS SELECT * FROM tbl'
3528
3529        Args:
3530            table: the SQL code string to parse as the table name.
3531                If another `Expression` instance is passed, it will be used as-is.
3532            properties: an optional mapping of table properties
3533            dialect: the dialect used to parse the input table.
3534            copy: if `False`, modify this expression instance in-place.
3535            opts: other options to use to parse the input table.
3536
3537        Returns:
3538            The new Create expression.
3539        """
3540        instance = maybe_copy(self, copy)
3541        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3542
3543        properties_expression = None
3544        if properties:
3545            properties_expression = Properties.from_dict(properties)
3546
3547        return Create(
3548            this=table_expression,
3549            kind="TABLE",
3550            expression=instance,
3551            properties=properties_expression,
3552        )
3553
3554    def lock(self, update: bool = True, copy: bool = True) -> Select:
3555        """
3556        Set the locking read mode for this expression.
3557
3558        Examples:
3559            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3560            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3561
3562            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3563            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3564
3565        Args:
3566            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3567            copy: if `False`, modify this expression instance in-place.
3568
3569        Returns:
3570            The modified expression.
3571        """
3572        inst = maybe_copy(self, copy)
3573        inst.set("locks", [Lock(update=update)])
3574
3575        return inst
3576
3577    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3578        """
3579        Set hints for this expression.
3580
3581        Examples:
3582            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3583            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3584
3585        Args:
3586            hints: The SQL code strings to parse as the hints.
3587                If an `Expression` instance is passed, it will be used as-is.
3588            dialect: The dialect used to parse the hints.
3589            copy: If `False`, modify this expression instance in-place.
3590
3591        Returns:
3592            The modified expression.
3593        """
3594        inst = maybe_copy(self, copy)
3595        inst.set(
3596            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3597        )
3598
3599        return inst
3600
3601    @property
3602    def named_selects(self) -> t.List[str]:
3603        return [e.output_name for e in self.expressions if e.alias_or_name]
3604
3605    @property
3606    def is_star(self) -> bool:
3607        return any(expression.is_star for expression in self.expressions)
3608
3609    @property
3610    def selects(self) -> t.List[Expression]:
3611        return self.expressions
3612
3613
3614UNWRAPPED_QUERIES = (Select, Union)
3615
3616
3617class Subquery(DerivedTable, Query):
3618    arg_types = {
3619        "this": True,
3620        "alias": False,
3621        "with": False,
3622        **QUERY_MODIFIERS,
3623    }
3624
3625    def unnest(self):
3626        """Returns the first non subquery."""
3627        expression = self
3628        while isinstance(expression, Subquery):
3629            expression = expression.this
3630        return expression
3631
3632    def unwrap(self) -> Subquery:
3633        expression = self
3634        while expression.same_parent and expression.is_wrapper:
3635            expression = t.cast(Subquery, expression.parent)
3636        return expression
3637
3638    def select(
3639        self,
3640        *expressions: t.Optional[ExpOrStr],
3641        append: bool = True,
3642        dialect: DialectType = None,
3643        copy: bool = True,
3644        **opts,
3645    ) -> Subquery:
3646        this = maybe_copy(self, copy)
3647        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3648        return this
3649
3650    @property
3651    def is_wrapper(self) -> bool:
3652        """
3653        Whether this Subquery acts as a simple wrapper around another expression.
3654
3655        SELECT * FROM (((SELECT * FROM t)))
3656                      ^
3657                      This corresponds to a "wrapper" Subquery node
3658        """
3659        return all(v is None for k, v in self.args.items() if k != "this")
3660
3661    @property
3662    def is_star(self) -> bool:
3663        return self.this.is_star
3664
3665    @property
3666    def output_name(self) -> str:
3667        return self.alias
3668
3669
3670class TableSample(Expression):
3671    arg_types = {
3672        "this": False,
3673        "expressions": False,
3674        "method": False,
3675        "bucket_numerator": False,
3676        "bucket_denominator": False,
3677        "bucket_field": False,
3678        "percent": False,
3679        "rows": False,
3680        "size": False,
3681        "seed": False,
3682    }
3683
3684
3685class Tag(Expression):
3686    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3687
3688    arg_types = {
3689        "this": False,
3690        "prefix": False,
3691        "postfix": False,
3692    }
3693
3694
3695# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
3696# https://duckdb.org/docs/sql/statements/pivot
3697class Pivot(Expression):
3698    arg_types = {
3699        "this": False,
3700        "alias": False,
3701        "expressions": False,
3702        "field": False,
3703        "unpivot": False,
3704        "using": False,
3705        "group": False,
3706        "columns": False,
3707        "include_nulls": False,
3708    }
3709
3710    @property
3711    def unpivot(self) -> bool:
3712        return bool(self.args.get("unpivot"))
3713
3714
3715class Window(Condition):
3716    arg_types = {
3717        "this": True,
3718        "partition_by": False,
3719        "order": False,
3720        "spec": False,
3721        "alias": False,
3722        "over": False,
3723        "first": False,
3724    }
3725
3726
3727class WindowSpec(Expression):
3728    arg_types = {
3729        "kind": False,
3730        "start": False,
3731        "start_side": False,
3732        "end": False,
3733        "end_side": False,
3734    }
3735
3736
3737class PreWhere(Expression):
3738    pass
3739
3740
3741class Where(Expression):
3742    pass
3743
3744
3745class Star(Expression):
3746    arg_types = {"except": False, "replace": False}
3747
3748    @property
3749    def name(self) -> str:
3750        return "*"
3751
3752    @property
3753    def output_name(self) -> str:
3754        return self.name
3755
3756
3757class Parameter(Condition):
3758    arg_types = {"this": True, "expression": False}
3759
3760
3761class SessionParameter(Condition):
3762    arg_types = {"this": True, "kind": False}
3763
3764
3765class Placeholder(Condition):
3766    arg_types = {"this": False, "kind": False}
3767
3768
3769class Null(Condition):
3770    arg_types: t.Dict[str, t.Any] = {}
3771
3772    @property
3773    def name(self) -> str:
3774        return "NULL"
3775
3776
3777class Boolean(Condition):
3778    pass
3779
3780
3781class DataTypeParam(Expression):
3782    arg_types = {"this": True, "expression": False}
3783
3784    @property
3785    def name(self) -> str:
3786        return self.this.name
3787
3788
3789class DataType(Expression):
3790    arg_types = {
3791        "this": True,
3792        "expressions": False,
3793        "nested": False,
3794        "values": False,
3795        "prefix": False,
3796        "kind": False,
3797    }
3798
3799    class Type(AutoName):
3800        ARRAY = auto()
3801        AGGREGATEFUNCTION = auto()
3802        SIMPLEAGGREGATEFUNCTION = auto()
3803        BIGDECIMAL = auto()
3804        BIGINT = auto()
3805        BIGSERIAL = auto()
3806        BINARY = auto()
3807        BIT = auto()
3808        BOOLEAN = auto()
3809        BPCHAR = auto()
3810        CHAR = auto()
3811        DATE = auto()
3812        DATE32 = auto()
3813        DATEMULTIRANGE = auto()
3814        DATERANGE = auto()
3815        DATETIME = auto()
3816        DATETIME64 = auto()
3817        DECIMAL = auto()
3818        DOUBLE = auto()
3819        ENUM = auto()
3820        ENUM8 = auto()
3821        ENUM16 = auto()
3822        FIXEDSTRING = auto()
3823        FLOAT = auto()
3824        GEOGRAPHY = auto()
3825        GEOMETRY = auto()
3826        HLLSKETCH = auto()
3827        HSTORE = auto()
3828        IMAGE = auto()
3829        INET = auto()
3830        INT = auto()
3831        INT128 = auto()
3832        INT256 = auto()
3833        INT4MULTIRANGE = auto()
3834        INT4RANGE = auto()
3835        INT8MULTIRANGE = auto()
3836        INT8RANGE = auto()
3837        INTERVAL = auto()
3838        IPADDRESS = auto()
3839        IPPREFIX = auto()
3840        IPV4 = auto()
3841        IPV6 = auto()
3842        JSON = auto()
3843        JSONB = auto()
3844        LONGBLOB = auto()
3845        LONGTEXT = auto()
3846        LOWCARDINALITY = auto()
3847        MAP = auto()
3848        MEDIUMBLOB = auto()
3849        MEDIUMINT = auto()
3850        MEDIUMTEXT = auto()
3851        MONEY = auto()
3852        NAME = auto()
3853        NCHAR = auto()
3854        NESTED = auto()
3855        NULL = auto()
3856        NULLABLE = auto()
3857        NUMMULTIRANGE = auto()
3858        NUMRANGE = auto()
3859        NVARCHAR = auto()
3860        OBJECT = auto()
3861        ROWVERSION = auto()
3862        SERIAL = auto()
3863        SET = auto()
3864        SMALLINT = auto()
3865        SMALLMONEY = auto()
3866        SMALLSERIAL = auto()
3867        STRUCT = auto()
3868        SUPER = auto()
3869        TEXT = auto()
3870        TINYBLOB = auto()
3871        TINYTEXT = auto()
3872        TIME = auto()
3873        TIMETZ = auto()
3874        TIMESTAMP = auto()
3875        TIMESTAMPLTZ = auto()
3876        TIMESTAMPTZ = auto()
3877        TIMESTAMP_S = auto()
3878        TIMESTAMP_MS = auto()
3879        TIMESTAMP_NS = auto()
3880        TINYINT = auto()
3881        TSMULTIRANGE = auto()
3882        TSRANGE = auto()
3883        TSTZMULTIRANGE = auto()
3884        TSTZRANGE = auto()
3885        UBIGINT = auto()
3886        UINT = auto()
3887        UINT128 = auto()
3888        UINT256 = auto()
3889        UMEDIUMINT = auto()
3890        UDECIMAL = auto()
3891        UNIQUEIDENTIFIER = auto()
3892        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3893        USERDEFINED = "USER-DEFINED"
3894        USMALLINT = auto()
3895        UTINYINT = auto()
3896        UUID = auto()
3897        VARBINARY = auto()
3898        VARCHAR = auto()
3899        VARIANT = auto()
3900        XML = auto()
3901        YEAR = auto()
3902
3903    STRUCT_TYPES = {
3904        Type.NESTED,
3905        Type.OBJECT,
3906        Type.STRUCT,
3907    }
3908
3909    NESTED_TYPES = {
3910        *STRUCT_TYPES,
3911        Type.ARRAY,
3912        Type.MAP,
3913    }
3914
3915    TEXT_TYPES = {
3916        Type.CHAR,
3917        Type.NCHAR,
3918        Type.NVARCHAR,
3919        Type.TEXT,
3920        Type.VARCHAR,
3921        Type.NAME,
3922    }
3923
3924    INTEGER_TYPES = {
3925        Type.BIGINT,
3926        Type.BIT,
3927        Type.INT,
3928        Type.INT128,
3929        Type.INT256,
3930        Type.MEDIUMINT,
3931        Type.SMALLINT,
3932        Type.TINYINT,
3933        Type.UBIGINT,
3934        Type.UINT,
3935        Type.UINT128,
3936        Type.UINT256,
3937        Type.UMEDIUMINT,
3938        Type.USMALLINT,
3939        Type.UTINYINT,
3940    }
3941
3942    FLOAT_TYPES = {
3943        Type.DOUBLE,
3944        Type.FLOAT,
3945    }
3946
3947    REAL_TYPES = {
3948        *FLOAT_TYPES,
3949        Type.BIGDECIMAL,
3950        Type.DECIMAL,
3951        Type.MONEY,
3952        Type.SMALLMONEY,
3953        Type.UDECIMAL,
3954    }
3955
3956    NUMERIC_TYPES = {
3957        *INTEGER_TYPES,
3958        *REAL_TYPES,
3959    }
3960
3961    TEMPORAL_TYPES = {
3962        Type.DATE,
3963        Type.DATE32,
3964        Type.DATETIME,
3965        Type.DATETIME64,
3966        Type.TIME,
3967        Type.TIMESTAMP,
3968        Type.TIMESTAMPLTZ,
3969        Type.TIMESTAMPTZ,
3970        Type.TIMESTAMP_MS,
3971        Type.TIMESTAMP_NS,
3972        Type.TIMESTAMP_S,
3973        Type.TIMETZ,
3974    }
3975
3976    @classmethod
3977    def build(
3978        cls,
3979        dtype: DATA_TYPE,
3980        dialect: DialectType = None,
3981        udt: bool = False,
3982        copy: bool = True,
3983        **kwargs,
3984    ) -> DataType:
3985        """
3986        Constructs a DataType object.
3987
3988        Args:
3989            dtype: the data type of interest.
3990            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3991            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3992                DataType, thus creating a user-defined type.
3993            copy: whether to copy the data type.
3994            kwargs: additional arguments to pass in the constructor of DataType.
3995
3996        Returns:
3997            The constructed DataType object.
3998        """
3999        from sqlglot import parse_one
4000
4001        if isinstance(dtype, str):
4002            if dtype.upper() == "UNKNOWN":
4003                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4004
4005            try:
4006                data_type_exp = parse_one(
4007                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4008                )
4009            except ParseError:
4010                if udt:
4011                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4012                raise
4013        elif isinstance(dtype, DataType.Type):
4014            data_type_exp = DataType(this=dtype)
4015        elif isinstance(dtype, DataType):
4016            return maybe_copy(dtype, copy)
4017        else:
4018            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4019
4020        return DataType(**{**data_type_exp.args, **kwargs})
4021
4022    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4023        """
4024        Checks whether this DataType matches one of the provided data types. Nested types or precision
4025        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4026
4027        Args:
4028            dtypes: the data types to compare this DataType to.
4029
4030        Returns:
4031            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4032        """
4033        for dtype in dtypes:
4034            other = DataType.build(dtype, copy=False, udt=True)
4035
4036            if (
4037                other.expressions
4038                or self.this == DataType.Type.USERDEFINED
4039                or other.this == DataType.Type.USERDEFINED
4040            ):
4041                matches = self == other
4042            else:
4043                matches = self.this == other.this
4044
4045            if matches:
4046                return True
4047        return False
4048
4049
4050DATA_TYPE = t.Union[str, DataType, DataType.Type]
4051
4052
4053# https://www.postgresql.org/docs/15/datatype-pseudo.html
4054class PseudoType(DataType):
4055    arg_types = {"this": True}
4056
4057
4058# https://www.postgresql.org/docs/15/datatype-oid.html
4059class ObjectIdentifier(DataType):
4060    arg_types = {"this": True}
4061
4062
4063# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4064class SubqueryPredicate(Predicate):
4065    pass
4066
4067
4068class All(SubqueryPredicate):
4069    pass
4070
4071
4072class Any(SubqueryPredicate):
4073    pass
4074
4075
4076class Exists(SubqueryPredicate):
4077    pass
4078
4079
4080# Commands to interact with the databases or engines. For most of the command
4081# expressions we parse whatever comes after the command's name as a string.
4082class Command(Expression):
4083    arg_types = {"this": True, "expression": False}
4084
4085
4086class Transaction(Expression):
4087    arg_types = {"this": False, "modes": False, "mark": False}
4088
4089
4090class Commit(Expression):
4091    arg_types = {"chain": False, "this": False, "durability": False}
4092
4093
4094class Rollback(Expression):
4095    arg_types = {"savepoint": False, "this": False}
4096
4097
4098class AlterTable(Expression):
4099    arg_types = {
4100        "this": True,
4101        "actions": True,
4102        "exists": False,
4103        "only": False,
4104        "options": False,
4105    }
4106
4107
4108class AddConstraint(Expression):
4109    arg_types = {"expressions": True}
4110
4111
4112class DropPartition(Expression):
4113    arg_types = {"expressions": True, "exists": False}
4114
4115
4116# Binary expressions like (ADD a b)
4117class Binary(Condition):
4118    arg_types = {"this": True, "expression": True}
4119
4120    @property
4121    def left(self) -> Expression:
4122        return self.this
4123
4124    @property
4125    def right(self) -> Expression:
4126        return self.expression
4127
4128
4129class Add(Binary):
4130    pass
4131
4132
4133class Connector(Binary):
4134    pass
4135
4136
4137class And(Connector):
4138    pass
4139
4140
4141class Or(Connector):
4142    pass
4143
4144
4145class BitwiseAnd(Binary):
4146    pass
4147
4148
4149class BitwiseLeftShift(Binary):
4150    pass
4151
4152
4153class BitwiseOr(Binary):
4154    pass
4155
4156
4157class BitwiseRightShift(Binary):
4158    pass
4159
4160
4161class BitwiseXor(Binary):
4162    pass
4163
4164
4165class Div(Binary):
4166    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4167
4168
4169class Overlaps(Binary):
4170    pass
4171
4172
4173class Dot(Binary):
4174    @property
4175    def is_star(self) -> bool:
4176        return self.expression.is_star
4177
4178    @property
4179    def name(self) -> str:
4180        return self.expression.name
4181
4182    @property
4183    def output_name(self) -> str:
4184        return self.name
4185
4186    @classmethod
4187    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4188        """Build a Dot object with a sequence of expressions."""
4189        if len(expressions) < 2:
4190            raise ValueError("Dot requires >= 2 expressions.")
4191
4192        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4193
4194    @property
4195    def parts(self) -> t.List[Expression]:
4196        """Return the parts of a table / column in order catalog, db, table."""
4197        this, *parts = self.flatten()
4198
4199        parts.reverse()
4200
4201        for arg in ("this", "table", "db", "catalog"):
4202            part = this.args.get(arg)
4203
4204            if isinstance(part, Expression):
4205                parts.append(part)
4206
4207        parts.reverse()
4208        return parts
4209
4210
4211class DPipe(Binary):
4212    arg_types = {"this": True, "expression": True, "safe": False}
4213
4214
4215class EQ(Binary, Predicate):
4216    pass
4217
4218
4219class NullSafeEQ(Binary, Predicate):
4220    pass
4221
4222
4223class NullSafeNEQ(Binary, Predicate):
4224    pass
4225
4226
4227# Represents e.g. := in DuckDB which is mostly used for setting parameters
4228class PropertyEQ(Binary):
4229    pass
4230
4231
4232class Distance(Binary):
4233    pass
4234
4235
4236class Escape(Binary):
4237    pass
4238
4239
4240class Glob(Binary, Predicate):
4241    pass
4242
4243
4244class GT(Binary, Predicate):
4245    pass
4246
4247
4248class GTE(Binary, Predicate):
4249    pass
4250
4251
4252class ILike(Binary, Predicate):
4253    pass
4254
4255
4256class ILikeAny(Binary, Predicate):
4257    pass
4258
4259
4260class IntDiv(Binary):
4261    pass
4262
4263
4264class Is(Binary, Predicate):
4265    pass
4266
4267
4268class Kwarg(Binary):
4269    """Kwarg in special functions like func(kwarg => y)."""
4270
4271
4272class Like(Binary, Predicate):
4273    pass
4274
4275
4276class LikeAny(Binary, Predicate):
4277    pass
4278
4279
4280class LT(Binary, Predicate):
4281    pass
4282
4283
4284class LTE(Binary, Predicate):
4285    pass
4286
4287
4288class Mod(Binary):
4289    pass
4290
4291
4292class Mul(Binary):
4293    pass
4294
4295
4296class NEQ(Binary, Predicate):
4297    pass
4298
4299
4300# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
4301class Operator(Binary):
4302    arg_types = {"this": True, "operator": True, "expression": True}
4303
4304
4305class SimilarTo(Binary, Predicate):
4306    pass
4307
4308
4309class Slice(Binary):
4310    arg_types = {"this": False, "expression": False}
4311
4312
4313class Sub(Binary):
4314    pass
4315
4316
4317# Unary Expressions
4318# (NOT a)
4319class Unary(Condition):
4320    pass
4321
4322
4323class BitwiseNot(Unary):
4324    pass
4325
4326
4327class Not(Unary):
4328    pass
4329
4330
4331class Paren(Unary):
4332    @property
4333    def output_name(self) -> str:
4334        return self.this.name
4335
4336
4337class Neg(Unary):
4338    pass
4339
4340
4341class Alias(Expression):
4342    arg_types = {"this": True, "alias": False}
4343
4344    @property
4345    def output_name(self) -> str:
4346        return self.alias
4347
4348
4349# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
4350# other dialects require identifiers. This enables us to transpile between them easily.
4351class PivotAlias(Alias):
4352    pass
4353
4354
4355class Aliases(Expression):
4356    arg_types = {"this": True, "expressions": True}
4357
4358    @property
4359    def aliases(self):
4360        return self.expressions
4361
4362
4363# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
4364class AtIndex(Expression):
4365    arg_types = {"this": True, "expression": True}
4366
4367
4368class AtTimeZone(Expression):
4369    arg_types = {"this": True, "zone": True}
4370
4371
4372class FromTimeZone(Expression):
4373    arg_types = {"this": True, "zone": True}
4374
4375
4376class Between(Predicate):
4377    arg_types = {"this": True, "low": True, "high": True}
4378
4379
4380class Bracket(Condition):
4381    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4382    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4383
4384    @property
4385    def output_name(self) -> str:
4386        if len(self.expressions) == 1:
4387            return self.expressions[0].output_name
4388
4389        return super().output_name
4390
4391
4392class Distinct(Expression):
4393    arg_types = {"expressions": False, "on": False}
4394
4395
4396class In(Predicate):
4397    arg_types = {
4398        "this": True,
4399        "expressions": False,
4400        "query": False,
4401        "unnest": False,
4402        "field": False,
4403        "is_global": False,
4404    }
4405
4406
4407# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
4408class ForIn(Expression):
4409    arg_types = {"this": True, "expression": True}
4410
4411
4412class TimeUnit(Expression):
4413    """Automatically converts unit arg into a var."""
4414
4415    arg_types = {"unit": False}
4416
4417    UNABBREVIATED_UNIT_NAME = {
4418        "D": "DAY",
4419        "H": "HOUR",
4420        "M": "MINUTE",
4421        "MS": "MILLISECOND",
4422        "NS": "NANOSECOND",
4423        "Q": "QUARTER",
4424        "S": "SECOND",
4425        "US": "MICROSECOND",
4426        "W": "WEEK",
4427        "Y": "YEAR",
4428    }
4429
4430    VAR_LIKE = (Column, Literal, Var)
4431
4432    def __init__(self, **args):
4433        unit = args.get("unit")
4434        if isinstance(unit, self.VAR_LIKE):
4435            args["unit"] = Var(
4436                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4437            )
4438        elif isinstance(unit, Week):
4439            unit.set("this", Var(this=unit.this.name.upper()))
4440
4441        super().__init__(**args)
4442
4443    @property
4444    def unit(self) -> t.Optional[Var]:
4445        return self.args.get("unit")
4446
4447
4448class IntervalOp(TimeUnit):
4449    arg_types = {"unit": True, "expression": True}
4450
4451    def interval(self):
4452        return Interval(
4453            this=self.expression.copy(),
4454            unit=self.unit.copy(),
4455        )
4456
4457
4458# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4459# https://trino.io/docs/current/language/types.html#interval-day-to-second
4460# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4461class IntervalSpan(DataType):
4462    arg_types = {"this": True, "expression": True}
4463
4464
4465class Interval(TimeUnit):
4466    arg_types = {"this": False, "unit": False}
4467
4468
4469class IgnoreNulls(Expression):
4470    pass
4471
4472
4473class RespectNulls(Expression):
4474    pass
4475
4476
4477# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
4478class HavingMax(Expression):
4479    arg_types = {"this": True, "expression": True, "max": True}
4480
4481
4482# Functions
4483class Func(Condition):
4484    """
4485    The base class for all function expressions.
4486
4487    Attributes:
4488        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4489            treated as a variable length argument and the argument's value will be stored as a list.
4490        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4491            function expression. These values are used to map this node to a name during parsing as
4492            well as to provide the function's name during SQL string generation. By default the SQL
4493            name is set to the expression's class name transformed to snake case.
4494    """
4495
4496    is_var_len_args = False
4497
4498    @classmethod
4499    def from_arg_list(cls, args):
4500        if cls.is_var_len_args:
4501            all_arg_keys = list(cls.arg_types)
4502            # If this function supports variable length argument treat the last argument as such.
4503            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4504            num_non_var = len(non_var_len_arg_keys)
4505
4506            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4507            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4508        else:
4509            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4510
4511        return cls(**args_dict)
4512
4513    @classmethod
4514    def sql_names(cls):
4515        if cls is Func:
4516            raise NotImplementedError(
4517                "SQL name is only supported by concrete function implementations"
4518            )
4519        if "_sql_names" not in cls.__dict__:
4520            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4521        return cls._sql_names
4522
4523    @classmethod
4524    def sql_name(cls):
4525        return cls.sql_names()[0]
4526
4527    @classmethod
4528    def default_parser_mappings(cls):
4529        return {name: cls.from_arg_list for name in cls.sql_names()}
4530
4531
4532class AggFunc(Func):
4533    pass
4534
4535
4536class ParameterizedAgg(AggFunc):
4537    arg_types = {"this": True, "expressions": True, "params": True}
4538
4539
4540class Abs(Func):
4541    pass
4542
4543
4544class ArgMax(AggFunc):
4545    arg_types = {"this": True, "expression": True, "count": False}
4546    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4547
4548
4549class ArgMin(AggFunc):
4550    arg_types = {"this": True, "expression": True, "count": False}
4551    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4552
4553
4554class ApproxTopK(AggFunc):
4555    arg_types = {"this": True, "expression": False, "counters": False}
4556
4557
4558class Flatten(Func):
4559    pass
4560
4561
4562# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4563class Transform(Func):
4564    arg_types = {"this": True, "expression": True}
4565
4566
4567class Anonymous(Func):
4568    arg_types = {"this": True, "expressions": False}
4569    is_var_len_args = True
4570
4571    @property
4572    def name(self) -> str:
4573        return self.this if isinstance(self.this, str) else self.this.name
4574
4575
4576class AnonymousAggFunc(AggFunc):
4577    arg_types = {"this": True, "expressions": False}
4578    is_var_len_args = True
4579
4580
4581# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
4582class CombinedAggFunc(AnonymousAggFunc):
4583    arg_types = {"this": True, "expressions": False, "parts": True}
4584
4585
4586class CombinedParameterizedAgg(ParameterizedAgg):
4587    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
4588
4589
4590# https://docs.snowflake.com/en/sql-reference/functions/hll
4591# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4592class Hll(AggFunc):
4593    arg_types = {"this": True, "expressions": False}
4594    is_var_len_args = True
4595
4596
4597class ApproxDistinct(AggFunc):
4598    arg_types = {"this": True, "accuracy": False}
4599    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4600
4601
4602class Array(Func):
4603    arg_types = {"expressions": False}
4604    is_var_len_args = True
4605
4606
4607# https://docs.snowflake.com/en/sql-reference/functions/to_array
4608class ToArray(Func):
4609    pass
4610
4611
4612# https://docs.snowflake.com/en/sql-reference/functions/to_char
4613# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4614class ToChar(Func):
4615    arg_types = {"this": True, "format": False, "nlsparam": False}
4616
4617
4618# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
4619# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
4620class ToNumber(Func):
4621    arg_types = {
4622        "this": True,
4623        "format": False,
4624        "nlsparam": False,
4625        "precision": False,
4626        "scale": False,
4627    }
4628
4629
4630# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
4631class Convert(Func):
4632    arg_types = {"this": True, "expression": True, "style": False}
4633
4634
4635class GenerateSeries(Func):
4636    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
4637
4638
4639class ArrayAgg(AggFunc):
4640    pass
4641
4642
4643class ArrayUniqueAgg(AggFunc):
4644    pass
4645
4646
4647class ArrayAll(Func):
4648    arg_types = {"this": True, "expression": True}
4649
4650
4651# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
4652class ArrayAny(Func):
4653    arg_types = {"this": True, "expression": True}
4654
4655
4656class ArrayConcat(Func):
4657    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4658    arg_types = {"this": True, "expressions": False}
4659    is_var_len_args = True
4660
4661
4662class ArrayContains(Binary, Func):
4663    pass
4664
4665
4666class ArrayContained(Binary):
4667    pass
4668
4669
4670class ArrayFilter(Func):
4671    arg_types = {"this": True, "expression": True}
4672    _sql_names = ["FILTER", "ARRAY_FILTER"]
4673
4674
4675class ArrayToString(Func):
4676    arg_types = {"this": True, "expression": True, "null": False}
4677    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
4678
4679
4680class ArrayOverlaps(Binary, Func):
4681    pass
4682
4683
4684class ArraySize(Func):
4685    arg_types = {"this": True, "expression": False}
4686    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
4687
4688
4689class ArraySort(Func):
4690    arg_types = {"this": True, "expression": False}
4691
4692
4693class ArraySum(Func):
4694    arg_types = {"this": True, "expression": False}
4695
4696
4697class ArrayUnionAgg(AggFunc):
4698    pass
4699
4700
4701class Avg(AggFunc):
4702    pass
4703
4704
4705class AnyValue(AggFunc):
4706    pass
4707
4708
4709class Lag(AggFunc):
4710    arg_types = {"this": True, "offset": False, "default": False}
4711
4712
4713class Lead(AggFunc):
4714    arg_types = {"this": True, "offset": False, "default": False}
4715
4716
4717# some dialects have a distinction between first and first_value, usually first is an aggregate func
4718# and first_value is a window func
4719class First(AggFunc):
4720    pass
4721
4722
4723class Last(AggFunc):
4724    pass
4725
4726
4727class FirstValue(AggFunc):
4728    pass
4729
4730
4731class LastValue(AggFunc):
4732    pass
4733
4734
4735class NthValue(AggFunc):
4736    arg_types = {"this": True, "offset": True}
4737
4738
4739class Case(Func):
4740    arg_types = {"this": False, "ifs": True, "default": False}
4741
4742    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4743        instance = maybe_copy(self, copy)
4744        instance.append(
4745            "ifs",
4746            If(
4747                this=maybe_parse(condition, copy=copy, **opts),
4748                true=maybe_parse(then, copy=copy, **opts),
4749            ),
4750        )
4751        return instance
4752
4753    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4754        instance = maybe_copy(self, copy)
4755        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4756        return instance
4757
4758
4759class Cast(Func):
4760    arg_types = {
4761        "this": True,
4762        "to": True,
4763        "format": False,
4764        "safe": False,
4765        "action": False,
4766    }
4767
4768    @property
4769    def name(self) -> str:
4770        return self.this.name
4771
4772    @property
4773    def to(self) -> DataType:
4774        return self.args["to"]
4775
4776    @property
4777    def output_name(self) -> str:
4778        return self.name
4779
4780    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4781        """
4782        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4783        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4784        array<int> != array<float>.
4785
4786        Args:
4787            dtypes: the data types to compare this Cast's DataType to.
4788
4789        Returns:
4790            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4791        """
4792        return self.to.is_type(*dtypes)
4793
4794
4795class TryCast(Cast):
4796    pass
4797
4798
4799class CastToStrType(Func):
4800    arg_types = {"this": True, "to": True}
4801
4802
4803class Collate(Binary, Func):
4804    pass
4805
4806
4807class Ceil(Func):
4808    arg_types = {"this": True, "decimals": False}
4809    _sql_names = ["CEIL", "CEILING"]
4810
4811
4812class Coalesce(Func):
4813    arg_types = {"this": True, "expressions": False}
4814    is_var_len_args = True
4815    _sql_names = ["COALESCE", "IFNULL", "NVL"]
4816
4817
4818class Chr(Func):
4819    arg_types = {"this": True, "charset": False, "expressions": False}
4820    is_var_len_args = True
4821    _sql_names = ["CHR", "CHAR"]
4822
4823
4824class Concat(Func):
4825    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4826    is_var_len_args = True
4827
4828
4829class ConcatWs(Concat):
4830    _sql_names = ["CONCAT_WS"]
4831
4832
4833# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
4834class ConnectByRoot(Func):
4835    pass
4836
4837
4838class Count(AggFunc):
4839    arg_types = {"this": False, "expressions": False}
4840    is_var_len_args = True
4841
4842
4843class CountIf(AggFunc):
4844    _sql_names = ["COUNT_IF", "COUNTIF"]
4845
4846
4847# cube root
4848class Cbrt(Func):
4849    pass
4850
4851
4852class CurrentDate(Func):
4853    arg_types = {"this": False}
4854
4855
4856class CurrentDatetime(Func):
4857    arg_types = {"this": False}
4858
4859
4860class CurrentTime(Func):
4861    arg_types = {"this": False}
4862
4863
4864class CurrentTimestamp(Func):
4865    arg_types = {"this": False, "transaction": False}
4866
4867
4868class CurrentUser(Func):
4869    arg_types = {"this": False}
4870
4871
4872class DateAdd(Func, IntervalOp):
4873    arg_types = {"this": True, "expression": True, "unit": False}
4874
4875
4876class DateSub(Func, IntervalOp):
4877    arg_types = {"this": True, "expression": True, "unit": False}
4878
4879
4880class DateDiff(Func, TimeUnit):
4881    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4882    arg_types = {"this": True, "expression": True, "unit": False}
4883
4884
4885class DateTrunc(Func):
4886    arg_types = {"unit": True, "this": True, "zone": False}
4887
4888    def __init__(self, **args):
4889        unit = args.get("unit")
4890        if isinstance(unit, TimeUnit.VAR_LIKE):
4891            args["unit"] = Literal.string(
4892                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4893            )
4894        elif isinstance(unit, Week):
4895            unit.set("this", Literal.string(unit.this.name.upper()))
4896
4897        super().__init__(**args)
4898
4899    @property
4900    def unit(self) -> Expression:
4901        return self.args["unit"]
4902
4903
4904class DatetimeAdd(Func, IntervalOp):
4905    arg_types = {"this": True, "expression": True, "unit": False}
4906
4907
4908class DatetimeSub(Func, IntervalOp):
4909    arg_types = {"this": True, "expression": True, "unit": False}
4910
4911
4912class DatetimeDiff(Func, TimeUnit):
4913    arg_types = {"this": True, "expression": True, "unit": False}
4914
4915
4916class DatetimeTrunc(Func, TimeUnit):
4917    arg_types = {"this": True, "unit": True, "zone": False}
4918
4919
4920class DayOfWeek(Func):
4921    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
4922
4923
4924class DayOfMonth(Func):
4925    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
4926
4927
4928class DayOfYear(Func):
4929    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
4930
4931
4932class ToDays(Func):
4933    pass
4934
4935
4936class WeekOfYear(Func):
4937    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4938
4939
4940class MonthsBetween(Func):
4941    arg_types = {"this": True, "expression": True, "roundoff": False}
4942
4943
4944class LastDay(Func, TimeUnit):
4945    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4946    arg_types = {"this": True, "unit": False}
4947
4948
4949class Extract(Func):
4950    arg_types = {"this": True, "expression": True}
4951
4952
4953class Timestamp(Func):
4954    arg_types = {"this": False, "expression": False, "with_tz": False}
4955
4956
4957class TimestampAdd(Func, TimeUnit):
4958    arg_types = {"this": True, "expression": True, "unit": False}
4959
4960
4961class TimestampSub(Func, TimeUnit):
4962    arg_types = {"this": True, "expression": True, "unit": False}
4963
4964
4965class TimestampDiff(Func, TimeUnit):
4966    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4967    arg_types = {"this": True, "expression": True, "unit": False}
4968
4969
4970class TimestampTrunc(Func, TimeUnit):
4971    arg_types = {"this": True, "unit": True, "zone": False}
4972
4973
4974class TimeAdd(Func, TimeUnit):
4975    arg_types = {"this": True, "expression": True, "unit": False}
4976
4977
4978class TimeSub(Func, TimeUnit):
4979    arg_types = {"this": True, "expression": True, "unit": False}
4980
4981
4982class TimeDiff(Func, TimeUnit):
4983    arg_types = {"this": True, "expression": True, "unit": False}
4984
4985
4986class TimeTrunc(Func, TimeUnit):
4987    arg_types = {"this": True, "unit": True, "zone": False}
4988
4989
4990class DateFromParts(Func):
4991    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4992    arg_types = {"year": True, "month": True, "day": True}
4993
4994
4995class TimeFromParts(Func):
4996    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4997    arg_types = {
4998        "hour": True,
4999        "min": True,
5000        "sec": True,
5001        "nano": False,
5002        "fractions": False,
5003        "precision": False,
5004    }
5005
5006
5007class DateStrToDate(Func):
5008    pass
5009
5010
5011class DateToDateStr(Func):
5012    pass
5013
5014
5015class DateToDi(Func):
5016    pass
5017
5018
5019# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5020class Date(Func):
5021    arg_types = {"this": False, "zone": False, "expressions": False}
5022    is_var_len_args = True
5023
5024
5025class Day(Func):
5026    pass
5027
5028
5029class Decode(Func):
5030    arg_types = {"this": True, "charset": True, "replace": False}
5031
5032
5033class DiToDate(Func):
5034    pass
5035
5036
5037class Encode(Func):
5038    arg_types = {"this": True, "charset": True}
5039
5040
5041class Exp(Func):
5042    pass
5043
5044
5045# https://docs.snowflake.com/en/sql-reference/functions/flatten
5046class Explode(Func):
5047    arg_types = {"this": True, "expressions": False}
5048    is_var_len_args = True
5049
5050
5051class ExplodeOuter(Explode):
5052    pass
5053
5054
5055class Posexplode(Explode):
5056    pass
5057
5058
5059class PosexplodeOuter(Posexplode, ExplodeOuter):
5060    pass
5061
5062
5063class Floor(Func):
5064    arg_types = {"this": True, "decimals": False}
5065
5066
5067class FromBase64(Func):
5068    pass
5069
5070
5071class ToBase64(Func):
5072    pass
5073
5074
5075class GenerateDateArray(Func):
5076    arg_types = {"start": True, "end": True, "interval": False}
5077
5078
5079class Greatest(Func):
5080    arg_types = {"this": True, "expressions": False}
5081    is_var_len_args = True
5082
5083
5084class GroupConcat(AggFunc):
5085    arg_types = {"this": True, "separator": False}
5086
5087
5088class Hex(Func):
5089    pass
5090
5091
5092class Xor(Connector, Func):
5093    arg_types = {"this": False, "expression": False, "expressions": False}
5094
5095
5096class If(Func):
5097    arg_types = {"this": True, "true": True, "false": False}
5098    _sql_names = ["IF", "IIF"]
5099
5100
5101class Nullif(Func):
5102    arg_types = {"this": True, "expression": True}
5103
5104
5105class Initcap(Func):
5106    arg_types = {"this": True, "expression": False}
5107
5108
5109class IsNan(Func):
5110    _sql_names = ["IS_NAN", "ISNAN"]
5111
5112
5113class IsInf(Func):
5114    _sql_names = ["IS_INF", "ISINF"]
5115
5116
5117class JSONPath(Expression):
5118    arg_types = {"expressions": True}
5119
5120    @property
5121    def output_name(self) -> str:
5122        last_segment = self.expressions[-1].this
5123        return last_segment if isinstance(last_segment, str) else ""
5124
5125
5126class JSONPathPart(Expression):
5127    arg_types = {}
5128
5129
5130class JSONPathFilter(JSONPathPart):
5131    arg_types = {"this": True}
5132
5133
5134class JSONPathKey(JSONPathPart):
5135    arg_types = {"this": True}
5136
5137
5138class JSONPathRecursive(JSONPathPart):
5139    arg_types = {"this": False}
5140
5141
5142class JSONPathRoot(JSONPathPart):
5143    pass
5144
5145
5146class JSONPathScript(JSONPathPart):
5147    arg_types = {"this": True}
5148
5149
5150class JSONPathSlice(JSONPathPart):
5151    arg_types = {"start": False, "end": False, "step": False}
5152
5153
5154class JSONPathSelector(JSONPathPart):
5155    arg_types = {"this": True}
5156
5157
5158class JSONPathSubscript(JSONPathPart):
5159    arg_types = {"this": True}
5160
5161
5162class JSONPathUnion(JSONPathPart):
5163    arg_types = {"expressions": True}
5164
5165
5166class JSONPathWildcard(JSONPathPart):
5167    pass
5168
5169
5170class FormatJson(Expression):
5171    pass
5172
5173
5174class JSONKeyValue(Expression):
5175    arg_types = {"this": True, "expression": True}
5176
5177
5178class JSONObject(Func):
5179    arg_types = {
5180        "expressions": False,
5181        "null_handling": False,
5182        "unique_keys": False,
5183        "return_type": False,
5184        "encoding": False,
5185    }
5186
5187
5188class JSONObjectAgg(AggFunc):
5189    arg_types = {
5190        "expressions": False,
5191        "null_handling": False,
5192        "unique_keys": False,
5193        "return_type": False,
5194        "encoding": False,
5195    }
5196
5197
5198# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
5199class JSONArray(Func):
5200    arg_types = {
5201        "expressions": True,
5202        "null_handling": False,
5203        "return_type": False,
5204        "strict": False,
5205    }
5206
5207
5208# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
5209class JSONArrayAgg(Func):
5210    arg_types = {
5211        "this": True,
5212        "order": False,
5213        "null_handling": False,
5214        "return_type": False,
5215        "strict": False,
5216    }
5217
5218
5219# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5220# Note: parsing of JSON column definitions is currently incomplete.
5221class JSONColumnDef(Expression):
5222    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
5223
5224
5225class JSONSchema(Expression):
5226    arg_types = {"expressions": True}
5227
5228
5229# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5230class JSONTable(Func):
5231    arg_types = {
5232        "this": True,
5233        "schema": True,
5234        "path": False,
5235        "error_handling": False,
5236        "empty_handling": False,
5237    }
5238
5239
5240class OpenJSONColumnDef(Expression):
5241    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
5242
5243
5244class OpenJSON(Func):
5245    arg_types = {"this": True, "path": False, "expressions": False}
5246
5247
5248class JSONBContains(Binary):
5249    _sql_names = ["JSONB_CONTAINS"]
5250
5251
5252class JSONExtract(Binary, Func):
5253    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5254    _sql_names = ["JSON_EXTRACT"]
5255    is_var_len_args = True
5256
5257    @property
5258    def output_name(self) -> str:
5259        return self.expression.output_name if not self.expressions else ""
5260
5261
5262class JSONExtractScalar(Binary, Func):
5263    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5264    _sql_names = ["JSON_EXTRACT_SCALAR"]
5265    is_var_len_args = True
5266
5267    @property
5268    def output_name(self) -> str:
5269        return self.expression.output_name
5270
5271
5272class JSONBExtract(Binary, Func):
5273    _sql_names = ["JSONB_EXTRACT"]
5274
5275
5276class JSONBExtractScalar(Binary, Func):
5277    _sql_names = ["JSONB_EXTRACT_SCALAR"]
5278
5279
5280class JSONFormat(Func):
5281    arg_types = {"this": False, "options": False}
5282    _sql_names = ["JSON_FORMAT"]
5283
5284
5285# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
5286class JSONArrayContains(Binary, Predicate, Func):
5287    _sql_names = ["JSON_ARRAY_CONTAINS"]
5288
5289
5290class ParseJSON(Func):
5291    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5292    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5293    arg_types = {"this": True, "expressions": False}
5294    is_var_len_args = True
5295
5296
5297class Least(Func):
5298    arg_types = {"this": True, "expressions": False}
5299    is_var_len_args = True
5300
5301
5302class Left(Func):
5303    arg_types = {"this": True, "expression": True}
5304
5305
5306class Right(Func):
5307    arg_types = {"this": True, "expression": True}
5308
5309
5310class Length(Func):
5311    _sql_names = ["LENGTH", "LEN"]
5312
5313
5314class Levenshtein(Func):
5315    arg_types = {
5316        "this": True,
5317        "expression": False,
5318        "ins_cost": False,
5319        "del_cost": False,
5320        "sub_cost": False,
5321    }
5322
5323
5324class Ln(Func):
5325    pass
5326
5327
5328class Log(Func):
5329    arg_types = {"this": True, "expression": False}
5330
5331
5332class LogicalOr(AggFunc):
5333    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
5334
5335
5336class LogicalAnd(AggFunc):
5337    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
5338
5339
5340class Lower(Func):
5341    _sql_names = ["LOWER", "LCASE"]
5342
5343
5344class Map(Func):
5345    arg_types = {"keys": False, "values": False}
5346
5347    @property
5348    def keys(self) -> t.List[Expression]:
5349        keys = self.args.get("keys")
5350        return keys.expressions if keys else []
5351
5352    @property
5353    def values(self) -> t.List[Expression]:
5354        values = self.args.get("values")
5355        return values.expressions if values else []
5356
5357
5358# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
5359class ToMap(Func):
5360    pass
5361
5362
5363class MapFromEntries(Func):
5364    pass
5365
5366
5367class StarMap(Func):
5368    pass
5369
5370
5371class VarMap(Func):
5372    arg_types = {"keys": True, "values": True}
5373    is_var_len_args = True
5374
5375    @property
5376    def keys(self) -> t.List[Expression]:
5377        return self.args["keys"].expressions
5378
5379    @property
5380    def values(self) -> t.List[Expression]:
5381        return self.args["values"].expressions
5382
5383
5384# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
5385class MatchAgainst(Func):
5386    arg_types = {"this": True, "expressions": True, "modifier": False}
5387
5388
5389class Max(AggFunc):
5390    arg_types = {"this": True, "expressions": False}
5391    is_var_len_args = True
5392
5393
5394class MD5(Func):
5395    _sql_names = ["MD5"]
5396
5397
5398# Represents the variant of the MD5 function that returns a binary value
5399class MD5Digest(Func):
5400    _sql_names = ["MD5_DIGEST"]
5401
5402
5403class Min(AggFunc):
5404    arg_types = {"this": True, "expressions": False}
5405    is_var_len_args = True
5406
5407
5408class Month(Func):
5409    pass
5410
5411
5412class AddMonths(Func):
5413    arg_types = {"this": True, "expression": True}
5414
5415
5416class Nvl2(Func):
5417    arg_types = {"this": True, "true": True, "false": False}
5418
5419
5420# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5421class Predict(Func):
5422    arg_types = {"this": True, "expression": True, "params_struct": False}
5423
5424
5425class Pow(Binary, Func):
5426    _sql_names = ["POWER", "POW"]
5427
5428
5429class PercentileCont(AggFunc):
5430    arg_types = {"this": True, "expression": False}
5431
5432
5433class PercentileDisc(AggFunc):
5434    arg_types = {"this": True, "expression": False}
5435
5436
5437class Quantile(AggFunc):
5438    arg_types = {"this": True, "quantile": True}
5439
5440
5441class ApproxQuantile(Quantile):
5442    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5443
5444
5445class Rand(Func):
5446    _sql_names = ["RAND", "RANDOM"]
5447    arg_types = {"this": False}
5448
5449
5450class Randn(Func):
5451    arg_types = {"this": False}
5452
5453
5454class RangeN(Func):
5455    arg_types = {"this": True, "expressions": True, "each": False}
5456
5457
5458class ReadCSV(Func):
5459    _sql_names = ["READ_CSV"]
5460    is_var_len_args = True
5461    arg_types = {"this": True, "expressions": False}
5462
5463
5464class Reduce(Func):
5465    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5466
5467
5468class RegexpExtract(Func):
5469    arg_types = {
5470        "this": True,
5471        "expression": True,
5472        "position": False,
5473        "occurrence": False,
5474        "parameters": False,
5475        "group": False,
5476    }
5477
5478
5479class RegexpReplace(Func):
5480    arg_types = {
5481        "this": True,
5482        "expression": True,
5483        "replacement": False,
5484        "position": False,
5485        "occurrence": False,
5486        "parameters": False,
5487        "modifiers": False,
5488    }
5489
5490
5491class RegexpLike(Binary, Func):
5492    arg_types = {"this": True, "expression": True, "flag": False}
5493
5494
5495class RegexpILike(Binary, Func):
5496    arg_types = {"this": True, "expression": True, "flag": False}
5497
5498
5499# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5500# limit is the number of times a pattern is applied
5501class RegexpSplit(Func):
5502    arg_types = {"this": True, "expression": True, "limit": False}
5503
5504
5505class Repeat(Func):
5506    arg_types = {"this": True, "times": True}
5507
5508
5509# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
5510# tsql third argument function == trunctaion if not 0
5511class Round(Func):
5512    arg_types = {"this": True, "decimals": False, "truncate": False}
5513
5514
5515class RowNumber(Func):
5516    arg_types: t.Dict[str, t.Any] = {}
5517
5518
5519class SafeDivide(Func):
5520    arg_types = {"this": True, "expression": True}
5521
5522
5523class SHA(Func):
5524    _sql_names = ["SHA", "SHA1"]
5525
5526
5527class SHA2(Func):
5528    _sql_names = ["SHA2"]
5529    arg_types = {"this": True, "length": False}
5530
5531
5532class Sign(Func):
5533    _sql_names = ["SIGN", "SIGNUM"]
5534
5535
5536class SortArray(Func):
5537    arg_types = {"this": True, "asc": False}
5538
5539
5540class Split(Func):
5541    arg_types = {"this": True, "expression": True, "limit": False}
5542
5543
5544# Start may be omitted in the case of postgres
5545# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5546class Substring(Func):
5547    arg_types = {"this": True, "start": False, "length": False}
5548
5549
5550class StandardHash(Func):
5551    arg_types = {"this": True, "expression": False}
5552
5553
5554class StartsWith(Func):
5555    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5556    arg_types = {"this": True, "expression": True}
5557
5558
5559class StrPosition(Func):
5560    arg_types = {
5561        "this": True,
5562        "substr": True,
5563        "position": False,
5564        "instance": False,
5565    }
5566
5567
5568class StrToDate(Func):
5569    arg_types = {"this": True, "format": True}
5570
5571
5572class StrToTime(Func):
5573    arg_types = {"this": True, "format": True, "zone": False}
5574
5575
5576# Spark allows unix_timestamp()
5577# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5578class StrToUnix(Func):
5579    arg_types = {"this": False, "format": False}
5580
5581
5582# https://prestodb.io/docs/current/functions/string.html
5583# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5584class StrToMap(Func):
5585    arg_types = {
5586        "this": True,
5587        "pair_delim": False,
5588        "key_value_delim": False,
5589        "duplicate_resolution_callback": False,
5590    }
5591
5592
5593class NumberToStr(Func):
5594    arg_types = {"this": True, "format": True, "culture": False}
5595
5596
5597class FromBase(Func):
5598    arg_types = {"this": True, "expression": True}
5599
5600
5601class Struct(Func):
5602    arg_types = {"expressions": False}
5603    is_var_len_args = True
5604
5605
5606class StructExtract(Func):
5607    arg_types = {"this": True, "expression": True}
5608
5609
5610# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5611# https://docs.snowflake.com/en/sql-reference/functions/insert
5612class Stuff(Func):
5613    _sql_names = ["STUFF", "INSERT"]
5614    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5615
5616
5617class Sum(AggFunc):
5618    pass
5619
5620
5621class Sqrt(Func):
5622    pass
5623
5624
5625class Stddev(AggFunc):
5626    pass
5627
5628
5629class StddevPop(AggFunc):
5630    pass
5631
5632
5633class StddevSamp(AggFunc):
5634    pass
5635
5636
5637class TimeToStr(Func):
5638    arg_types = {"this": True, "format": True, "culture": False}
5639
5640
5641class TimeToTimeStr(Func):
5642    pass
5643
5644
5645class TimeToUnix(Func):
5646    pass
5647
5648
5649class TimeStrToDate(Func):
5650    pass
5651
5652
5653class TimeStrToTime(Func):
5654    pass
5655
5656
5657class TimeStrToUnix(Func):
5658    pass
5659
5660
5661class Trim(Func):
5662    arg_types = {
5663        "this": True,
5664        "expression": False,
5665        "position": False,
5666        "collation": False,
5667    }
5668
5669
5670class TsOrDsAdd(Func, TimeUnit):
5671    # return_type is used to correctly cast the arguments of this expression when transpiling it
5672    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5673
5674    @property
5675    def return_type(self) -> DataType:
5676        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5677
5678
5679class TsOrDsDiff(Func, TimeUnit):
5680    arg_types = {"this": True, "expression": True, "unit": False}
5681
5682
5683class TsOrDsToDateStr(Func):
5684    pass
5685
5686
5687class TsOrDsToDate(Func):
5688    arg_types = {"this": True, "format": False, "safe": False}
5689
5690
5691class TsOrDsToTime(Func):
5692    pass
5693
5694
5695class TsOrDsToTimestamp(Func):
5696    pass
5697
5698
5699class TsOrDiToDi(Func):
5700    pass
5701
5702
5703class Unhex(Func):
5704    pass
5705
5706
5707# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5708class UnixDate(Func):
5709    pass
5710
5711
5712class UnixToStr(Func):
5713    arg_types = {"this": True, "format": False}
5714
5715
5716# https://prestodb.io/docs/current/functions/datetime.html
5717# presto has weird zone/hours/minutes
5718class UnixToTime(Func):
5719    arg_types = {
5720        "this": True,
5721        "scale": False,
5722        "zone": False,
5723        "hours": False,
5724        "minutes": False,
5725        "format": False,
5726    }
5727
5728    SECONDS = Literal.number(0)
5729    DECIS = Literal.number(1)
5730    CENTIS = Literal.number(2)
5731    MILLIS = Literal.number(3)
5732    DECIMILLIS = Literal.number(4)
5733    CENTIMILLIS = Literal.number(5)
5734    MICROS = Literal.number(6)
5735    DECIMICROS = Literal.number(7)
5736    CENTIMICROS = Literal.number(8)
5737    NANOS = Literal.number(9)
5738
5739
5740class UnixToTimeStr(Func):
5741    pass
5742
5743
5744class TimestampFromParts(Func):
5745    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5746    arg_types = {
5747        "year": True,
5748        "month": True,
5749        "day": True,
5750        "hour": True,
5751        "min": True,
5752        "sec": True,
5753        "nano": False,
5754        "zone": False,
5755        "milli": False,
5756    }
5757
5758
5759class Upper(Func):
5760    _sql_names = ["UPPER", "UCASE"]
5761
5762
5763class Corr(Binary, AggFunc):
5764    pass
5765
5766
5767class Variance(AggFunc):
5768    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5769
5770
5771class VariancePop(AggFunc):
5772    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5773
5774
5775class CovarSamp(Binary, AggFunc):
5776    pass
5777
5778
5779class CovarPop(Binary, AggFunc):
5780    pass
5781
5782
5783class Week(Func):
5784    arg_types = {"this": True, "mode": False}
5785
5786
5787class XMLTable(Func):
5788    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5789
5790
5791class Year(Func):
5792    pass
5793
5794
5795class Use(Expression):
5796    arg_types = {"this": True, "kind": False}
5797
5798
5799class Merge(Expression):
5800    arg_types = {
5801        "this": True,
5802        "using": True,
5803        "on": True,
5804        "expressions": True,
5805        "with": False,
5806    }
5807
5808
5809class When(Func):
5810    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5811
5812
5813# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5814# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5815class NextValueFor(Func):
5816    arg_types = {"this": True, "order": False}
5817
5818
5819def _norm_arg(arg):
5820    return arg.lower() if type(arg) is str else arg
5821
5822
5823ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5824FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
5825
5826JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
5827
5828
5829# Helpers
5830@t.overload
5831def maybe_parse(
5832    sql_or_expression: ExpOrStr,
5833    *,
5834    into: t.Type[E],
5835    dialect: DialectType = None,
5836    prefix: t.Optional[str] = None,
5837    copy: bool = False,
5838    **opts,
5839) -> E: ...
5840
5841
5842@t.overload
5843def maybe_parse(
5844    sql_or_expression: str | E,
5845    *,
5846    into: t.Optional[IntoType] = None,
5847    dialect: DialectType = None,
5848    prefix: t.Optional[str] = None,
5849    copy: bool = False,
5850    **opts,
5851) -> E: ...
5852
5853
5854def maybe_parse(
5855    sql_or_expression: ExpOrStr,
5856    *,
5857    into: t.Optional[IntoType] = None,
5858    dialect: DialectType = None,
5859    prefix: t.Optional[str] = None,
5860    copy: bool = False,
5861    **opts,
5862) -> Expression:
5863    """Gracefully handle a possible string or expression.
5864
5865    Example:
5866        >>> maybe_parse("1")
5867        Literal(this=1, is_string=False)
5868        >>> maybe_parse(to_identifier("x"))
5869        Identifier(this=x, quoted=False)
5870
5871    Args:
5872        sql_or_expression: the SQL code string or an expression
5873        into: the SQLGlot Expression to parse into
5874        dialect: the dialect used to parse the input expressions (in the case that an
5875            input expression is a SQL string).
5876        prefix: a string to prefix the sql with before it gets parsed
5877            (automatically includes a space)
5878        copy: whether to copy the expression.
5879        **opts: other options to use to parse the input expressions (again, in the case
5880            that an input expression is a SQL string).
5881
5882    Returns:
5883        Expression: the parsed or given expression.
5884    """
5885    if isinstance(sql_or_expression, Expression):
5886        if copy:
5887            return sql_or_expression.copy()
5888        return sql_or_expression
5889
5890    if sql_or_expression is None:
5891        raise ParseError("SQL cannot be None")
5892
5893    import sqlglot
5894
5895    sql = str(sql_or_expression)
5896    if prefix:
5897        sql = f"{prefix} {sql}"
5898
5899    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5900
5901
5902@t.overload
5903def maybe_copy(instance: None, copy: bool = True) -> None: ...
5904
5905
5906@t.overload
5907def maybe_copy(instance: E, copy: bool = True) -> E: ...
5908
5909
5910def maybe_copy(instance, copy=True):
5911    return instance.copy() if copy and instance else instance
5912
5913
5914def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
5915    """Generate a textual representation of an Expression tree"""
5916    indent = "\n" + ("  " * (level + 1))
5917    delim = f",{indent}"
5918
5919    if isinstance(node, Expression):
5920        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
5921
5922        if (node.type or verbose) and not isinstance(node, DataType):
5923            args["_type"] = node.type
5924        if node.comments or verbose:
5925            args["_comments"] = node.comments
5926
5927        if verbose:
5928            args["_id"] = id(node)
5929
5930        # Inline leaves for a more compact representation
5931        if node.is_leaf():
5932            indent = ""
5933            delim = ", "
5934
5935        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
5936        return f"{node.__class__.__name__}({indent}{items})"
5937
5938    if isinstance(node, list):
5939        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
5940        items = f"{indent}{items}" if items else ""
5941        return f"[{items}]"
5942
5943    # Indent multiline strings to match the current level
5944    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
5945
5946
5947def _is_wrong_expression(expression, into):
5948    return isinstance(expression, Expression) and not isinstance(expression, into)
5949
5950
5951def _apply_builder(
5952    expression,
5953    instance,
5954    arg,
5955    copy=True,
5956    prefix=None,
5957    into=None,
5958    dialect=None,
5959    into_arg="this",
5960    **opts,
5961):
5962    if _is_wrong_expression(expression, into):
5963        expression = into(**{into_arg: expression})
5964    instance = maybe_copy(instance, copy)
5965    expression = maybe_parse(
5966        sql_or_expression=expression,
5967        prefix=prefix,
5968        into=into,
5969        dialect=dialect,
5970        **opts,
5971    )
5972    instance.set(arg, expression)
5973    return instance
5974
5975
5976def _apply_child_list_builder(
5977    *expressions,
5978    instance,
5979    arg,
5980    append=True,
5981    copy=True,
5982    prefix=None,
5983    into=None,
5984    dialect=None,
5985    properties=None,
5986    **opts,
5987):
5988    instance = maybe_copy(instance, copy)
5989    parsed = []
5990    for expression in expressions:
5991        if expression is not None:
5992            if _is_wrong_expression(expression, into):
5993                expression = into(expressions=[expression])
5994
5995            expression = maybe_parse(
5996                expression,
5997                into=into,
5998                dialect=dialect,
5999                prefix=prefix,
6000                **opts,
6001            )
6002            parsed.extend(expression.expressions)
6003
6004    existing = instance.args.get(arg)
6005    if append and existing:
6006        parsed = existing.expressions + parsed
6007
6008    child = into(expressions=parsed)
6009    for k, v in (properties or {}).items():
6010        child.set(k, v)
6011    instance.set(arg, child)
6012
6013    return instance
6014
6015
6016def _apply_list_builder(
6017    *expressions,
6018    instance,
6019    arg,
6020    append=True,
6021    copy=True,
6022    prefix=None,
6023    into=None,
6024    dialect=None,
6025    **opts,
6026):
6027    inst = maybe_copy(instance, copy)
6028
6029    expressions = [
6030        maybe_parse(
6031            sql_or_expression=expression,
6032            into=into,
6033            prefix=prefix,
6034            dialect=dialect,
6035            **opts,
6036        )
6037        for expression in expressions
6038        if expression is not None
6039    ]
6040
6041    existing_expressions = inst.args.get(arg)
6042    if append and existing_expressions:
6043        expressions = existing_expressions + expressions
6044
6045    inst.set(arg, expressions)
6046    return inst
6047
6048
6049def _apply_conjunction_builder(
6050    *expressions,
6051    instance,
6052    arg,
6053    into=None,
6054    append=True,
6055    copy=True,
6056    dialect=None,
6057    **opts,
6058):
6059    expressions = [exp for exp in expressions if exp is not None and exp != ""]
6060    if not expressions:
6061        return instance
6062
6063    inst = maybe_copy(instance, copy)
6064
6065    existing = inst.args.get(arg)
6066    if append and existing is not None:
6067        expressions = [existing.this if into else existing] + list(expressions)
6068
6069    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
6070
6071    inst.set(arg, into(this=node) if into else node)
6072    return inst
6073
6074
6075def _apply_cte_builder(
6076    instance: E,
6077    alias: ExpOrStr,
6078    as_: ExpOrStr,
6079    recursive: t.Optional[bool] = None,
6080    append: bool = True,
6081    dialect: DialectType = None,
6082    copy: bool = True,
6083    **opts,
6084) -> E:
6085    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
6086    as_expression = maybe_parse(as_, dialect=dialect, **opts)
6087    cte = CTE(this=as_expression, alias=alias_expression)
6088    return _apply_child_list_builder(
6089        cte,
6090        instance=instance,
6091        arg="with",
6092        append=append,
6093        copy=copy,
6094        into=With,
6095        properties={"recursive": recursive or False},
6096    )
6097
6098
6099def _combine(
6100    expressions: t.Sequence[t.Optional[ExpOrStr]],
6101    operator: t.Type[Connector],
6102    dialect: DialectType = None,
6103    copy: bool = True,
6104    **opts,
6105) -> Expression:
6106    conditions = [
6107        condition(expression, dialect=dialect, copy=copy, **opts)
6108        for expression in expressions
6109        if expression is not None
6110    ]
6111
6112    this, *rest = conditions
6113    if rest:
6114        this = _wrap(this, Connector)
6115    for expression in rest:
6116        this = operator(this=this, expression=_wrap(expression, Connector))
6117
6118    return this
6119
6120
6121def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
6122    return Paren(this=expression) if isinstance(expression, kind) else expression
6123
6124
6125def union(
6126    left: ExpOrStr,
6127    right: ExpOrStr,
6128    distinct: bool = True,
6129    dialect: DialectType = None,
6130    copy: bool = True,
6131    **opts,
6132) -> Union:
6133    """
6134    Initializes a syntax tree from one UNION expression.
6135
6136    Example:
6137        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6138        'SELECT * FROM foo UNION SELECT * FROM bla'
6139
6140    Args:
6141        left: the SQL code string corresponding to the left-hand side.
6142            If an `Expression` instance is passed, it will be used as-is.
6143        right: the SQL code string corresponding to the right-hand side.
6144            If an `Expression` instance is passed, it will be used as-is.
6145        distinct: set the DISTINCT flag if and only if this is true.
6146        dialect: the dialect used to parse the input expression.
6147        copy: whether to copy the expression.
6148        opts: other options to use to parse the input expressions.
6149
6150    Returns:
6151        The new Union instance.
6152    """
6153    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6154    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6155
6156    return Union(this=left, expression=right, distinct=distinct)
6157
6158
6159def intersect(
6160    left: ExpOrStr,
6161    right: ExpOrStr,
6162    distinct: bool = True,
6163    dialect: DialectType = None,
6164    copy: bool = True,
6165    **opts,
6166) -> Intersect:
6167    """
6168    Initializes a syntax tree from one INTERSECT expression.
6169
6170    Example:
6171        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6172        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6173
6174    Args:
6175        left: the SQL code string corresponding to the left-hand side.
6176            If an `Expression` instance is passed, it will be used as-is.
6177        right: the SQL code string corresponding to the right-hand side.
6178            If an `Expression` instance is passed, it will be used as-is.
6179        distinct: set the DISTINCT flag if and only if this is true.
6180        dialect: the dialect used to parse the input expression.
6181        copy: whether to copy the expression.
6182        opts: other options to use to parse the input expressions.
6183
6184    Returns:
6185        The new Intersect instance.
6186    """
6187    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6188    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6189
6190    return Intersect(this=left, expression=right, distinct=distinct)
6191
6192
6193def except_(
6194    left: ExpOrStr,
6195    right: ExpOrStr,
6196    distinct: bool = True,
6197    dialect: DialectType = None,
6198    copy: bool = True,
6199    **opts,
6200) -> Except:
6201    """
6202    Initializes a syntax tree from one EXCEPT expression.
6203
6204    Example:
6205        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6206        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6207
6208    Args:
6209        left: the SQL code string corresponding to the left-hand side.
6210            If an `Expression` instance is passed, it will be used as-is.
6211        right: the SQL code string corresponding to the right-hand side.
6212            If an `Expression` instance is passed, it will be used as-is.
6213        distinct: set the DISTINCT flag if and only if this is true.
6214        dialect: the dialect used to parse the input expression.
6215        copy: whether to copy the expression.
6216        opts: other options to use to parse the input expressions.
6217
6218    Returns:
6219        The new Except instance.
6220    """
6221    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6222    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6223
6224    return Except(this=left, expression=right, distinct=distinct)
6225
6226
6227def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6228    """
6229    Initializes a syntax tree from one or multiple SELECT expressions.
6230
6231    Example:
6232        >>> select("col1", "col2").from_("tbl").sql()
6233        'SELECT col1, col2 FROM tbl'
6234
6235    Args:
6236        *expressions: the SQL code string to parse as the expressions of a
6237            SELECT statement. If an Expression instance is passed, this is used as-is.
6238        dialect: the dialect used to parse the input expressions (in the case that an
6239            input expression is a SQL string).
6240        **opts: other options to use to parse the input expressions (again, in the case
6241            that an input expression is a SQL string).
6242
6243    Returns:
6244        Select: the syntax tree for the SELECT statement.
6245    """
6246    return Select().select(*expressions, dialect=dialect, **opts)
6247
6248
6249def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6250    """
6251    Initializes a syntax tree from a FROM expression.
6252
6253    Example:
6254        >>> from_("tbl").select("col1", "col2").sql()
6255        'SELECT col1, col2 FROM tbl'
6256
6257    Args:
6258        *expression: the SQL code string to parse as the FROM expressions of a
6259            SELECT statement. If an Expression instance is passed, this is used as-is.
6260        dialect: the dialect used to parse the input expression (in the case that the
6261            input expression is a SQL string).
6262        **opts: other options to use to parse the input expressions (again, in the case
6263            that the input expression is a SQL string).
6264
6265    Returns:
6266        Select: the syntax tree for the SELECT statement.
6267    """
6268    return Select().from_(expression, dialect=dialect, **opts)
6269
6270
6271def update(
6272    table: str | Table,
6273    properties: dict,
6274    where: t.Optional[ExpOrStr] = None,
6275    from_: t.Optional[ExpOrStr] = None,
6276    dialect: DialectType = None,
6277    **opts,
6278) -> Update:
6279    """
6280    Creates an update statement.
6281
6282    Example:
6283        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6284        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6285
6286    Args:
6287        *properties: dictionary of properties to set which are
6288            auto converted to sql objects eg None -> NULL
6289        where: sql conditional parsed into a WHERE statement
6290        from_: sql statement parsed into a FROM statement
6291        dialect: the dialect used to parse the input expressions.
6292        **opts: other options to use to parse the input expressions.
6293
6294    Returns:
6295        Update: the syntax tree for the UPDATE statement.
6296    """
6297    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6298    update_expr.set(
6299        "expressions",
6300        [
6301            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6302            for k, v in properties.items()
6303        ],
6304    )
6305    if from_:
6306        update_expr.set(
6307            "from",
6308            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6309        )
6310    if isinstance(where, Condition):
6311        where = Where(this=where)
6312    if where:
6313        update_expr.set(
6314            "where",
6315            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6316        )
6317    return update_expr
6318
6319
6320def delete(
6321    table: ExpOrStr,
6322    where: t.Optional[ExpOrStr] = None,
6323    returning: t.Optional[ExpOrStr] = None,
6324    dialect: DialectType = None,
6325    **opts,
6326) -> Delete:
6327    """
6328    Builds a delete statement.
6329
6330    Example:
6331        >>> delete("my_table", where="id > 1").sql()
6332        'DELETE FROM my_table WHERE id > 1'
6333
6334    Args:
6335        where: sql conditional parsed into a WHERE statement
6336        returning: sql conditional parsed into a RETURNING statement
6337        dialect: the dialect used to parse the input expressions.
6338        **opts: other options to use to parse the input expressions.
6339
6340    Returns:
6341        Delete: the syntax tree for the DELETE statement.
6342    """
6343    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6344    if where:
6345        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6346    if returning:
6347        delete_expr = t.cast(
6348            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6349        )
6350    return delete_expr
6351
6352
6353def insert(
6354    expression: ExpOrStr,
6355    into: ExpOrStr,
6356    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6357    overwrite: t.Optional[bool] = None,
6358    returning: t.Optional[ExpOrStr] = None,
6359    dialect: DialectType = None,
6360    copy: bool = True,
6361    **opts,
6362) -> Insert:
6363    """
6364    Builds an INSERT statement.
6365
6366    Example:
6367        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6368        'INSERT INTO tbl VALUES (1, 2, 3)'
6369
6370    Args:
6371        expression: the sql string or expression of the INSERT statement
6372        into: the tbl to insert data to.
6373        columns: optionally the table's column names.
6374        overwrite: whether to INSERT OVERWRITE or not.
6375        returning: sql conditional parsed into a RETURNING statement
6376        dialect: the dialect used to parse the input expressions.
6377        copy: whether to copy the expression.
6378        **opts: other options to use to parse the input expressions.
6379
6380    Returns:
6381        Insert: the syntax tree for the INSERT statement.
6382    """
6383    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6384    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6385
6386    if columns:
6387        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6388
6389    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6390
6391    if returning:
6392        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6393
6394    return insert
6395
6396
6397def condition(
6398    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6399) -> Condition:
6400    """
6401    Initialize a logical condition expression.
6402
6403    Example:
6404        >>> condition("x=1").sql()
6405        'x = 1'
6406
6407        This is helpful for composing larger logical syntax trees:
6408        >>> where = condition("x=1")
6409        >>> where = where.and_("y=1")
6410        >>> Select().from_("tbl").select("*").where(where).sql()
6411        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6412
6413    Args:
6414        *expression: the SQL code string to parse.
6415            If an Expression instance is passed, this is used as-is.
6416        dialect: the dialect used to parse the input expression (in the case that the
6417            input expression is a SQL string).
6418        copy: Whether to copy `expression` (only applies to expressions).
6419        **opts: other options to use to parse the input expressions (again, in the case
6420            that the input expression is a SQL string).
6421
6422    Returns:
6423        The new Condition instance
6424    """
6425    return maybe_parse(
6426        expression,
6427        into=Condition,
6428        dialect=dialect,
6429        copy=copy,
6430        **opts,
6431    )
6432
6433
6434def and_(
6435    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6436) -> Condition:
6437    """
6438    Combine multiple conditions with an AND logical operator.
6439
6440    Example:
6441        >>> and_("x=1", and_("y=1", "z=1")).sql()
6442        'x = 1 AND (y = 1 AND z = 1)'
6443
6444    Args:
6445        *expressions: the SQL code strings to parse.
6446            If an Expression instance is passed, this is used as-is.
6447        dialect: the dialect used to parse the input expression.
6448        copy: whether to copy `expressions` (only applies to Expressions).
6449        **opts: other options to use to parse the input expressions.
6450
6451    Returns:
6452        And: the new condition
6453    """
6454    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6455
6456
6457def or_(
6458    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6459) -> Condition:
6460    """
6461    Combine multiple conditions with an OR logical operator.
6462
6463    Example:
6464        >>> or_("x=1", or_("y=1", "z=1")).sql()
6465        'x = 1 OR (y = 1 OR z = 1)'
6466
6467    Args:
6468        *expressions: the SQL code strings to parse.
6469            If an Expression instance is passed, this is used as-is.
6470        dialect: the dialect used to parse the input expression.
6471        copy: whether to copy `expressions` (only applies to Expressions).
6472        **opts: other options to use to parse the input expressions.
6473
6474    Returns:
6475        Or: the new condition
6476    """
6477    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6478
6479
6480def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6481    """
6482    Wrap a condition with a NOT operator.
6483
6484    Example:
6485        >>> not_("this_suit='black'").sql()
6486        "NOT this_suit = 'black'"
6487
6488    Args:
6489        expression: the SQL code string to parse.
6490            If an Expression instance is passed, this is used as-is.
6491        dialect: the dialect used to parse the input expression.
6492        copy: whether to copy the expression or not.
6493        **opts: other options to use to parse the input expressions.
6494
6495    Returns:
6496        The new condition.
6497    """
6498    this = condition(
6499        expression,
6500        dialect=dialect,
6501        copy=copy,
6502        **opts,
6503    )
6504    return Not(this=_wrap(this, Connector))
6505
6506
6507def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6508    """
6509    Wrap an expression in parentheses.
6510
6511    Example:
6512        >>> paren("5 + 3").sql()
6513        '(5 + 3)'
6514
6515    Args:
6516        expression: the SQL code string to parse.
6517            If an Expression instance is passed, this is used as-is.
6518        copy: whether to copy the expression or not.
6519
6520    Returns:
6521        The wrapped expression.
6522    """
6523    return Paren(this=maybe_parse(expression, copy=copy))
6524
6525
6526SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
6527
6528
6529@t.overload
6530def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
6531
6532
6533@t.overload
6534def to_identifier(
6535    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6536) -> Identifier: ...
6537
6538
6539def to_identifier(name, quoted=None, copy=True):
6540    """Builds an identifier.
6541
6542    Args:
6543        name: The name to turn into an identifier.
6544        quoted: Whether to force quote the identifier.
6545        copy: Whether to copy name if it's an Identifier.
6546
6547    Returns:
6548        The identifier ast node.
6549    """
6550
6551    if name is None:
6552        return None
6553
6554    if isinstance(name, Identifier):
6555        identifier = maybe_copy(name, copy)
6556    elif isinstance(name, str):
6557        identifier = Identifier(
6558            this=name,
6559            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6560        )
6561    else:
6562        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6563    return identifier
6564
6565
6566def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6567    """
6568    Parses a given string into an identifier.
6569
6570    Args:
6571        name: The name to parse into an identifier.
6572        dialect: The dialect to parse against.
6573
6574    Returns:
6575        The identifier ast node.
6576    """
6577    try:
6578        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6579    except ParseError:
6580        expression = to_identifier(name)
6581
6582    return expression
6583
6584
6585INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6586
6587
6588def to_interval(interval: str | Literal) -> Interval:
6589    """Builds an interval expression from a string like '1 day' or '5 months'."""
6590    if isinstance(interval, Literal):
6591        if not interval.is_string:
6592            raise ValueError("Invalid interval string.")
6593
6594        interval = interval.this
6595
6596    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6597
6598    if not interval_parts:
6599        raise ValueError("Invalid interval string.")
6600
6601    return Interval(
6602        this=Literal.string(interval_parts.group(1)),
6603        unit=Var(this=interval_parts.group(2).upper()),
6604    )
6605
6606
6607@t.overload
6608def to_table(sql_path: str | Table, **kwargs) -> Table: ...
6609
6610
6611@t.overload
6612def to_table(sql_path: None, **kwargs) -> None: ...
6613
6614
6615def to_table(
6616    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6617) -> t.Optional[Table]:
6618    """
6619    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6620    If a table is passed in then that table is returned.
6621
6622    Args:
6623        sql_path: a `[catalog].[schema].[table]` string.
6624        dialect: the source dialect according to which the table name will be parsed.
6625        copy: Whether to copy a table if it is passed in.
6626        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6627
6628    Returns:
6629        A table expression.
6630    """
6631    if sql_path is None or isinstance(sql_path, Table):
6632        return maybe_copy(sql_path, copy=copy)
6633    if not isinstance(sql_path, str):
6634        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6635
6636    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6637    if table:
6638        for k, v in kwargs.items():
6639            table.set(k, v)
6640
6641    return table
6642
6643
6644def to_column(sql_path: str | Column, **kwargs) -> Column:
6645    """
6646    Create a column from a `[table].[column]` sql path. Schema is optional.
6647
6648    If a column is passed in then that column is returned.
6649
6650    Args:
6651        sql_path: `[table].[column]` string
6652    Returns:
6653        Table: A column expression
6654    """
6655    if sql_path is None or isinstance(sql_path, Column):
6656        return sql_path
6657    if not isinstance(sql_path, str):
6658        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6659    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
6660
6661
6662def alias_(
6663    expression: ExpOrStr,
6664    alias: t.Optional[str | Identifier],
6665    table: bool | t.Sequence[str | Identifier] = False,
6666    quoted: t.Optional[bool] = None,
6667    dialect: DialectType = None,
6668    copy: bool = True,
6669    **opts,
6670):
6671    """Create an Alias expression.
6672
6673    Example:
6674        >>> alias_('foo', 'bar').sql()
6675        'foo AS bar'
6676
6677        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6678        '(SELECT 1, 2) AS bar(a, b)'
6679
6680    Args:
6681        expression: the SQL code strings to parse.
6682            If an Expression instance is passed, this is used as-is.
6683        alias: the alias name to use. If the name has
6684            special characters it is quoted.
6685        table: Whether to create a table alias, can also be a list of columns.
6686        quoted: whether to quote the alias
6687        dialect: the dialect used to parse the input expression.
6688        copy: Whether to copy the expression.
6689        **opts: other options to use to parse the input expressions.
6690
6691    Returns:
6692        Alias: the aliased expression
6693    """
6694    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6695    alias = to_identifier(alias, quoted=quoted)
6696
6697    if table:
6698        table_alias = TableAlias(this=alias)
6699        exp.set("alias", table_alias)
6700
6701        if not isinstance(table, bool):
6702            for column in table:
6703                table_alias.append("columns", to_identifier(column, quoted=quoted))
6704
6705        return exp
6706
6707    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6708    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6709    # for the complete Window expression.
6710    #
6711    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6712
6713    if "alias" in exp.arg_types and not isinstance(exp, Window):
6714        exp.set("alias", alias)
6715        return exp
6716    return Alias(this=exp, alias=alias)
6717
6718
6719def subquery(
6720    expression: ExpOrStr,
6721    alias: t.Optional[Identifier | str] = None,
6722    dialect: DialectType = None,
6723    **opts,
6724) -> Select:
6725    """
6726    Build a subquery expression that's selected from.
6727
6728    Example:
6729        >>> subquery('select x from tbl', 'bar').select('x').sql()
6730        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6731
6732    Args:
6733        expression: the SQL code strings to parse.
6734            If an Expression instance is passed, this is used as-is.
6735        alias: the alias name to use.
6736        dialect: the dialect used to parse the input expression.
6737        **opts: other options to use to parse the input expressions.
6738
6739    Returns:
6740        A new Select instance with the subquery expression included.
6741    """
6742
6743    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6744    return Select().from_(expression, dialect=dialect, **opts)
6745
6746
6747@t.overload
6748def column(
6749    col: str | Identifier,
6750    table: t.Optional[str | Identifier] = None,
6751    db: t.Optional[str | Identifier] = None,
6752    catalog: t.Optional[str | Identifier] = None,
6753    *,
6754    fields: t.Collection[t.Union[str, Identifier]],
6755    quoted: t.Optional[bool] = None,
6756    copy: bool = True,
6757) -> Dot:
6758    pass
6759
6760
6761@t.overload
6762def column(
6763    col: str | Identifier,
6764    table: t.Optional[str | Identifier] = None,
6765    db: t.Optional[str | Identifier] = None,
6766    catalog: t.Optional[str | Identifier] = None,
6767    *,
6768    fields: Lit[None] = None,
6769    quoted: t.Optional[bool] = None,
6770    copy: bool = True,
6771) -> Column:
6772    pass
6773
6774
6775def column(
6776    col,
6777    table=None,
6778    db=None,
6779    catalog=None,
6780    *,
6781    fields=None,
6782    quoted=None,
6783    copy=True,
6784):
6785    """
6786    Build a Column.
6787
6788    Args:
6789        col: Column name.
6790        table: Table name.
6791        db: Database name.
6792        catalog: Catalog name.
6793        fields: Additional fields using dots.
6794        quoted: Whether to force quotes on the column's identifiers.
6795        copy: Whether to copy identifiers if passed in.
6796
6797    Returns:
6798        The new Column instance.
6799    """
6800    this = Column(
6801        this=to_identifier(col, quoted=quoted, copy=copy),
6802        table=to_identifier(table, quoted=quoted, copy=copy),
6803        db=to_identifier(db, quoted=quoted, copy=copy),
6804        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6805    )
6806
6807    if fields:
6808        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6809    return this
6810
6811
6812def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6813    """Cast an expression to a data type.
6814
6815    Example:
6816        >>> cast('x + 1', 'int').sql()
6817        'CAST(x + 1 AS INT)'
6818
6819    Args:
6820        expression: The expression to cast.
6821        to: The datatype to cast to.
6822        copy: Whether to copy the supplied expressions.
6823
6824    Returns:
6825        The new Cast instance.
6826    """
6827    expression = maybe_parse(expression, copy=copy, **opts)
6828    data_type = DataType.build(to, copy=copy, **opts)
6829    expression = Cast(this=expression, to=data_type)
6830    expression.type = data_type
6831    return expression
6832
6833
6834def table_(
6835    table: Identifier | str,
6836    db: t.Optional[Identifier | str] = None,
6837    catalog: t.Optional[Identifier | str] = None,
6838    quoted: t.Optional[bool] = None,
6839    alias: t.Optional[Identifier | str] = None,
6840) -> Table:
6841    """Build a Table.
6842
6843    Args:
6844        table: Table name.
6845        db: Database name.
6846        catalog: Catalog name.
6847        quote: Whether to force quotes on the table's identifiers.
6848        alias: Table's alias.
6849
6850    Returns:
6851        The new Table instance.
6852    """
6853    return Table(
6854        this=to_identifier(table, quoted=quoted) if table else None,
6855        db=to_identifier(db, quoted=quoted) if db else None,
6856        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6857        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6858    )
6859
6860
6861def values(
6862    values: t.Iterable[t.Tuple[t.Any, ...]],
6863    alias: t.Optional[str] = None,
6864    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6865) -> Values:
6866    """Build VALUES statement.
6867
6868    Example:
6869        >>> values([(1, '2')]).sql()
6870        "VALUES (1, '2')"
6871
6872    Args:
6873        values: values statements that will be converted to SQL
6874        alias: optional alias
6875        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6876         If either are provided then an alias is also required.
6877
6878    Returns:
6879        Values: the Values expression object
6880    """
6881    if columns and not alias:
6882        raise ValueError("Alias is required when providing columns")
6883
6884    return Values(
6885        expressions=[convert(tup) for tup in values],
6886        alias=(
6887            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6888            if columns
6889            else (TableAlias(this=to_identifier(alias)) if alias else None)
6890        ),
6891    )
6892
6893
6894def var(name: t.Optional[ExpOrStr]) -> Var:
6895    """Build a SQL variable.
6896
6897    Example:
6898        >>> repr(var('x'))
6899        'Var(this=x)'
6900
6901        >>> repr(var(column('x', table='y')))
6902        'Var(this=x)'
6903
6904    Args:
6905        name: The name of the var or an expression who's name will become the var.
6906
6907    Returns:
6908        The new variable node.
6909    """
6910    if not name:
6911        raise ValueError("Cannot convert empty name into var.")
6912
6913    if isinstance(name, Expression):
6914        name = name.name
6915    return Var(this=name)
6916
6917
6918def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6919    """Build ALTER TABLE... RENAME... expression
6920
6921    Args:
6922        old_name: The old name of the table
6923        new_name: The new name of the table
6924
6925    Returns:
6926        Alter table expression
6927    """
6928    old_table = to_table(old_name)
6929    new_table = to_table(new_name)
6930    return AlterTable(
6931        this=old_table,
6932        actions=[
6933            RenameTable(this=new_table),
6934        ],
6935    )
6936
6937
6938def rename_column(
6939    table_name: str | Table,
6940    old_column_name: str | Column,
6941    new_column_name: str | Column,
6942    exists: t.Optional[bool] = None,
6943) -> AlterTable:
6944    """Build ALTER TABLE... RENAME COLUMN... expression
6945
6946    Args:
6947        table_name: Name of the table
6948        old_column: The old name of the column
6949        new_column: The new name of the column
6950        exists: Whether to add the `IF EXISTS` clause
6951
6952    Returns:
6953        Alter table expression
6954    """
6955    table = to_table(table_name)
6956    old_column = to_column(old_column_name)
6957    new_column = to_column(new_column_name)
6958    return AlterTable(
6959        this=table,
6960        actions=[
6961            RenameColumn(this=old_column, to=new_column, exists=exists),
6962        ],
6963    )
6964
6965
6966def convert(value: t.Any, copy: bool = False) -> Expression:
6967    """Convert a python value into an expression object.
6968
6969    Raises an error if a conversion is not possible.
6970
6971    Args:
6972        value: A python object.
6973        copy: Whether to copy `value` (only applies to Expressions and collections).
6974
6975    Returns:
6976        Expression: the equivalent expression object.
6977    """
6978    if isinstance(value, Expression):
6979        return maybe_copy(value, copy)
6980    if isinstance(value, str):
6981        return Literal.string(value)
6982    if isinstance(value, bool):
6983        return Boolean(this=value)
6984    if value is None or (isinstance(value, float) and math.isnan(value)):
6985        return null()
6986    if isinstance(value, numbers.Number):
6987        return Literal.number(value)
6988    if isinstance(value, bytes):
6989        return HexString(this=value.hex())
6990    if isinstance(value, datetime.datetime):
6991        datetime_literal = Literal.string(
6992            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
6993                sep=" "
6994            )
6995        )
6996        return TimeStrToTime(this=datetime_literal)
6997    if isinstance(value, datetime.date):
6998        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6999        return DateStrToDate(this=date_literal)
7000    if isinstance(value, tuple):
7001        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7002    if isinstance(value, list):
7003        return Array(expressions=[convert(v, copy=copy) for v in value])
7004    if isinstance(value, dict):
7005        return Map(
7006            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7007            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7008        )
7009    raise ValueError(f"Cannot convert {value}")
7010
7011
7012def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7013    """
7014    Replace children of an expression with the result of a lambda fun(child) -> exp.
7015    """
7016    for k, v in tuple(expression.args.items()):
7017        is_list_arg = type(v) is list
7018
7019        child_nodes = v if is_list_arg else [v]
7020        new_child_nodes = []
7021
7022        for cn in child_nodes:
7023            if isinstance(cn, Expression):
7024                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7025                    new_child_nodes.append(child_node)
7026            else:
7027                new_child_nodes.append(cn)
7028
7029        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
7030
7031
7032def replace_tree(
7033    expression: Expression,
7034    fun: t.Callable,
7035    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7036) -> Expression:
7037    """
7038    Replace an entire tree with the result of function calls on each node.
7039
7040    This will be traversed in reverse dfs, so leaves first.
7041    If new nodes are created as a result of function calls, they will also be traversed.
7042    """
7043    stack = list(expression.dfs(prune=prune))
7044
7045    while stack:
7046        node = stack.pop()
7047        new_node = fun(node)
7048
7049        if new_node is not node:
7050            node.replace(new_node)
7051
7052            if isinstance(new_node, Expression):
7053                stack.append(new_node)
7054
7055    return new_node
7056
7057
7058def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7059    """
7060    Return all table names referenced through columns in an expression.
7061
7062    Example:
7063        >>> import sqlglot
7064        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7065        ['a', 'c']
7066
7067    Args:
7068        expression: expression to find table names.
7069        exclude: a table name to exclude
7070
7071    Returns:
7072        A list of unique names.
7073    """
7074    return {
7075        table
7076        for table in (column.table for column in expression.find_all(Column))
7077        if table and table != exclude
7078    }
7079
7080
7081def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7082    """Get the full name of a table as a string.
7083
7084    Args:
7085        table: Table expression node or string.
7086        dialect: The dialect to generate the table name for.
7087        identify: Determines when an identifier should be quoted. Possible values are:
7088            False (default): Never quote, except in cases where it's mandatory by the dialect.
7089            True: Always quote.
7090
7091    Examples:
7092        >>> from sqlglot import exp, parse_one
7093        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7094        'a.b.c'
7095
7096    Returns:
7097        The table name.
7098    """
7099
7100    table = maybe_parse(table, into=Table, dialect=dialect)
7101
7102    if not table:
7103        raise ValueError(f"Cannot parse {table}")
7104
7105    return ".".join(
7106        (
7107            part.sql(dialect=dialect, identify=True, copy=False)
7108            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7109            else part.name
7110        )
7111        for part in table.parts
7112    )
7113
7114
7115def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7116    """Returns a case normalized table name without quotes.
7117
7118    Args:
7119        table: the table to normalize
7120        dialect: the dialect to use for normalization rules
7121        copy: whether to copy the expression.
7122
7123    Examples:
7124        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7125        'A-B.c'
7126    """
7127    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7128
7129    return ".".join(
7130        p.name
7131        for p in normalize_identifiers(
7132            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7133        ).parts
7134    )
7135
7136
7137def replace_tables(
7138    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7139) -> E:
7140    """Replace all tables in expression according to the mapping.
7141
7142    Args:
7143        expression: expression node to be transformed and replaced.
7144        mapping: mapping of table names.
7145        dialect: the dialect of the mapping table
7146        copy: whether to copy the expression.
7147
7148    Examples:
7149        >>> from sqlglot import exp, parse_one
7150        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7151        'SELECT * FROM c /* a.b */'
7152
7153    Returns:
7154        The mapped expression.
7155    """
7156
7157    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7158
7159    def _replace_tables(node: Expression) -> Expression:
7160        if isinstance(node, Table):
7161            original = normalize_table_name(node, dialect=dialect)
7162            new_name = mapping.get(original)
7163
7164            if new_name:
7165                table = to_table(
7166                    new_name,
7167                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7168                    dialect=dialect,
7169                )
7170                table.add_comments([original])
7171                return table
7172        return node
7173
7174    return expression.transform(_replace_tables, copy=copy)  # type: ignore
7175
7176
7177def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7178    """Replace placeholders in an expression.
7179
7180    Args:
7181        expression: expression node to be transformed and replaced.
7182        args: positional names that will substitute unnamed placeholders in the given order.
7183        kwargs: keyword arguments that will substitute named placeholders.
7184
7185    Examples:
7186        >>> from sqlglot import exp, parse_one
7187        >>> replace_placeholders(
7188        ...     parse_one("select * from :tbl where ? = ?"),
7189        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7190        ... ).sql()
7191        "SELECT * FROM foo WHERE str_col = 'b'"
7192
7193    Returns:
7194        The mapped expression.
7195    """
7196
7197    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7198        if isinstance(node, Placeholder):
7199            if node.name:
7200                new_name = kwargs.get(node.name)
7201                if new_name is not None:
7202                    return convert(new_name)
7203            else:
7204                try:
7205                    return convert(next(args))
7206                except StopIteration:
7207                    pass
7208        return node
7209
7210    return expression.transform(_replace_placeholders, iter(args), **kwargs)
7211
7212
7213def expand(
7214    expression: Expression,
7215    sources: t.Dict[str, Query],
7216    dialect: DialectType = None,
7217    copy: bool = True,
7218) -> Expression:
7219    """Transforms an expression by expanding all referenced sources into subqueries.
7220
7221    Examples:
7222        >>> from sqlglot import parse_one
7223        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7224        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7225
7226        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7227        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7228
7229    Args:
7230        expression: The expression to expand.
7231        sources: A dictionary of name to Queries.
7232        dialect: The dialect of the sources dict.
7233        copy: Whether to copy the expression during transformation. Defaults to True.
7234
7235    Returns:
7236        The transformed expression.
7237    """
7238    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7239
7240    def _expand(node: Expression):
7241        if isinstance(node, Table):
7242            name = normalize_table_name(node, dialect=dialect)
7243            source = sources.get(name)
7244            if source:
7245                subquery = source.subquery(node.alias or name)
7246                subquery.comments = [f"source: {name}"]
7247                return subquery.transform(_expand, copy=False)
7248        return node
7249
7250    return expression.transform(_expand, copy=copy)
7251
7252
7253def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7254    """
7255    Returns a Func expression.
7256
7257    Examples:
7258        >>> func("abs", 5).sql()
7259        'ABS(5)'
7260
7261        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7262        'CAST(5 AS DOUBLE)'
7263
7264    Args:
7265        name: the name of the function to build.
7266        args: the args used to instantiate the function of interest.
7267        copy: whether to copy the argument expressions.
7268        dialect: the source dialect.
7269        kwargs: the kwargs used to instantiate the function of interest.
7270
7271    Note:
7272        The arguments `args` and `kwargs` are mutually exclusive.
7273
7274    Returns:
7275        An instance of the function of interest, or an anonymous function, if `name` doesn't
7276        correspond to an existing `sqlglot.expressions.Func` class.
7277    """
7278    if args and kwargs:
7279        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7280
7281    from sqlglot.dialects.dialect import Dialect
7282
7283    dialect = Dialect.get_or_raise(dialect)
7284
7285    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7286    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7287
7288    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7289    if constructor:
7290        if converted:
7291            if "dialect" in constructor.__code__.co_varnames:
7292                function = constructor(converted, dialect=dialect)
7293            else:
7294                function = constructor(converted)
7295        elif constructor.__name__ == "from_arg_list":
7296            function = constructor.__self__(**kwargs)  # type: ignore
7297        else:
7298            constructor = FUNCTION_BY_NAME.get(name.upper())
7299            if constructor:
7300                function = constructor(**kwargs)
7301            else:
7302                raise ValueError(
7303                    f"Unable to convert '{name}' into a Func. Either manually construct "
7304                    "the Func expression of interest or parse the function call."
7305                )
7306    else:
7307        kwargs = kwargs or {"expressions": converted}
7308        function = Anonymous(this=name, **kwargs)
7309
7310    for error_message in function.error_messages(converted):
7311        raise ValueError(error_message)
7312
7313    return function
7314
7315
7316def case(
7317    expression: t.Optional[ExpOrStr] = None,
7318    **opts,
7319) -> Case:
7320    """
7321    Initialize a CASE statement.
7322
7323    Example:
7324        case().when("a = 1", "foo").else_("bar")
7325
7326    Args:
7327        expression: Optionally, the input expression (not all dialects support this)
7328        **opts: Extra keyword arguments for parsing `expression`
7329    """
7330    if expression is not None:
7331        this = maybe_parse(expression, **opts)
7332    else:
7333        this = None
7334    return Case(this=this, ifs=[])
7335
7336
7337def cast_unless(
7338    expression: ExpOrStr,
7339    to: DATA_TYPE,
7340    *types: DATA_TYPE,
7341    **opts: t.Any,
7342) -> Expression | Cast:
7343    """
7344    Cast an expression to a data type unless it is a specified type.
7345
7346    Args:
7347        expression: The expression to cast.
7348        to: The data type to cast to.
7349        **types: The types to exclude from casting.
7350        **opts: Extra keyword arguments for parsing `expression`
7351    """
7352    expr = maybe_parse(expression, **opts)
7353    if expr.is_type(*types):
7354        return expr
7355    return cast(expr, to, **opts)
7356
7357
7358def array(
7359    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7360) -> Array:
7361    """
7362    Returns an array.
7363
7364    Examples:
7365        >>> array(1, 'x').sql()
7366        'ARRAY(1, x)'
7367
7368    Args:
7369        expressions: the expressions to add to the array.
7370        copy: whether to copy the argument expressions.
7371        dialect: the source dialect.
7372        kwargs: the kwargs used to instantiate the function of interest.
7373
7374    Returns:
7375        An array expression.
7376    """
7377    return Array(
7378        expressions=[
7379            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7380            for expression in expressions
7381        ]
7382    )
7383
7384
7385def tuple_(
7386    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7387) -> Tuple:
7388    """
7389    Returns an tuple.
7390
7391    Examples:
7392        >>> tuple_(1, 'x').sql()
7393        '(1, x)'
7394
7395    Args:
7396        expressions: the expressions to add to the tuple.
7397        copy: whether to copy the argument expressions.
7398        dialect: the source dialect.
7399        kwargs: the kwargs used to instantiate the function of interest.
7400
7401    Returns:
7402        A tuple expression.
7403    """
7404    return Tuple(
7405        expressions=[
7406            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7407            for expression in expressions
7408        ]
7409    )
7410
7411
7412def true() -> Boolean:
7413    """
7414    Returns a true Boolean expression.
7415    """
7416    return Boolean(this=True)
7417
7418
7419def false() -> Boolean:
7420    """
7421    Returns a false Boolean expression.
7422    """
7423    return Boolean(this=False)
7424
7425
7426def null() -> Null:
7427    """
7428    Returns a Null expression.
7429    """
7430    return Null()
7431
7432
7433NONNULL_CONSTANTS = (
7434    Literal,
7435    Boolean,
7436)
7437
7438CONSTANTS = (
7439    Literal,
7440    Boolean,
7441    Null,
7442)
SQLGLOT_META = 'sqlglot.meta'
TABLE_PARTS = ('this', 'db', 'catalog')
class Expression:
 64class Expression(metaclass=_Expression):
 65    """
 66    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
 67    context, such as its child expressions, their names (arg keys), and whether a given child expression
 68    is optional or not.
 69
 70    Attributes:
 71        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
 72            and representing expressions as strings.
 73        arg_types: determines the arguments (child nodes) supported by an expression. It maps
 74            arg keys to booleans that indicate whether the corresponding args are optional.
 75        parent: a reference to the parent expression (or None, in case of root expressions).
 76        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
 77            uses to refer to it.
 78        index: the index of an expression if it is inside of a list argument in its parent.
 79        comments: a list of comments that are associated with a given expression. This is used in
 80            order to preserve comments when transpiling SQL code.
 81        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
 82            optimizer, in order to enable some transformations that require type information.
 83        meta: a dictionary that can be used to store useful metadata for a given expression.
 84
 85    Example:
 86        >>> class Foo(Expression):
 87        ...     arg_types = {"this": True, "expression": False}
 88
 89        The above definition informs us that Foo is an Expression that requires an argument called
 90        "this" and may also optionally receive an argument called "expression".
 91
 92    Args:
 93        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
 94    """
 95
 96    key = "expression"
 97    arg_types = {"this": True}
 98    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 99
100    def __init__(self, **args: t.Any):
101        self.args: t.Dict[str, t.Any] = args
102        self.parent: t.Optional[Expression] = None
103        self.arg_key: t.Optional[str] = None
104        self.index: t.Optional[int] = None
105        self.comments: t.Optional[t.List[str]] = None
106        self._type: t.Optional[DataType] = None
107        self._meta: t.Optional[t.Dict[str, t.Any]] = None
108        self._hash: t.Optional[int] = None
109
110        for arg_key, value in self.args.items():
111            self._set_parent(arg_key, value)
112
113    def __eq__(self, other) -> bool:
114        return type(self) is type(other) and hash(self) == hash(other)
115
116    @property
117    def hashable_args(self) -> t.Any:
118        return frozenset(
119            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
120            for k, v in self.args.items()
121            if not (v is None or v is False or (type(v) is list and not v))
122        )
123
124    def __hash__(self) -> int:
125        if self._hash is not None:
126            return self._hash
127
128        return hash((self.__class__, self.hashable_args))
129
130    @property
131    def this(self) -> t.Any:
132        """
133        Retrieves the argument with key "this".
134        """
135        return self.args.get("this")
136
137    @property
138    def expression(self) -> t.Any:
139        """
140        Retrieves the argument with key "expression".
141        """
142        return self.args.get("expression")
143
144    @property
145    def expressions(self) -> t.List[t.Any]:
146        """
147        Retrieves the argument with key "expressions".
148        """
149        return self.args.get("expressions") or []
150
151    def text(self, key) -> str:
152        """
153        Returns a textual representation of the argument corresponding to "key". This can only be used
154        for args that are strings or leaf Expression instances, such as identifiers and literals.
155        """
156        field = self.args.get(key)
157        if isinstance(field, str):
158            return field
159        if isinstance(field, (Identifier, Literal, Var)):
160            return field.this
161        if isinstance(field, (Star, Null)):
162            return field.name
163        return ""
164
165    @property
166    def is_string(self) -> bool:
167        """
168        Checks whether a Literal expression is a string.
169        """
170        return isinstance(self, Literal) and self.args["is_string"]
171
172    @property
173    def is_number(self) -> bool:
174        """
175        Checks whether a Literal expression is a number.
176        """
177        return isinstance(self, Literal) and not self.args["is_string"]
178
179    @property
180    def is_int(self) -> bool:
181        """
182        Checks whether a Literal expression is an integer.
183        """
184        return self.is_number and is_int(self.name)
185
186    @property
187    def is_star(self) -> bool:
188        """Checks whether an expression is a star."""
189        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
190
191    @property
192    def alias(self) -> str:
193        """
194        Returns the alias of the expression, or an empty string if it's not aliased.
195        """
196        if isinstance(self.args.get("alias"), TableAlias):
197            return self.args["alias"].name
198        return self.text("alias")
199
200    @property
201    def alias_column_names(self) -> t.List[str]:
202        table_alias = self.args.get("alias")
203        if not table_alias:
204            return []
205        return [c.name for c in table_alias.args.get("columns") or []]
206
207    @property
208    def name(self) -> str:
209        return self.text("this")
210
211    @property
212    def alias_or_name(self) -> str:
213        return self.alias or self.name
214
215    @property
216    def output_name(self) -> str:
217        """
218        Name of the output column if this expression is a selection.
219
220        If the Expression has no output name, an empty string is returned.
221
222        Example:
223            >>> from sqlglot import parse_one
224            >>> parse_one("SELECT a").expressions[0].output_name
225            'a'
226            >>> parse_one("SELECT b AS c").expressions[0].output_name
227            'c'
228            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
229            ''
230        """
231        return ""
232
233    @property
234    def type(self) -> t.Optional[DataType]:
235        return self._type
236
237    @type.setter
238    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
239        if dtype and not isinstance(dtype, DataType):
240            dtype = DataType.build(dtype)
241        self._type = dtype  # type: ignore
242
243    def is_type(self, *dtypes) -> bool:
244        return self.type is not None and self.type.is_type(*dtypes)
245
246    def is_leaf(self) -> bool:
247        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
248
249    @property
250    def meta(self) -> t.Dict[str, t.Any]:
251        if self._meta is None:
252            self._meta = {}
253        return self._meta
254
255    def __deepcopy__(self, memo):
256        root = self.__class__()
257        stack = [(self, root)]
258
259        while stack:
260            node, copy = stack.pop()
261
262            if node.comments is not None:
263                copy.comments = deepcopy(node.comments)
264            if node._type is not None:
265                copy._type = deepcopy(node._type)
266            if node._meta is not None:
267                copy._meta = deepcopy(node._meta)
268            if node._hash is not None:
269                copy._hash = node._hash
270
271            for k, vs in node.args.items():
272                if hasattr(vs, "parent"):
273                    stack.append((vs, vs.__class__()))
274                    copy.set(k, stack[-1][-1])
275                elif type(vs) is list:
276                    copy.args[k] = []
277
278                    for v in vs:
279                        if hasattr(v, "parent"):
280                            stack.append((v, v.__class__()))
281                            copy.append(k, stack[-1][-1])
282                        else:
283                            copy.append(k, v)
284                else:
285                    copy.args[k] = vs
286
287        return root
288
289    def copy(self):
290        """
291        Returns a deep copy of the expression.
292        """
293        return deepcopy(self)
294
295    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
296        if self.comments is None:
297            self.comments = []
298        if comments:
299            for comment in comments:
300                _, *meta = comment.split(SQLGLOT_META)
301                if meta:
302                    for kv in "".join(meta).split(","):
303                        k, *v = kv.split("=")
304                        value = v[0].strip() if v else True
305                        self.meta[k.strip()] = value
306                self.comments.append(comment)
307
308    def append(self, arg_key: str, value: t.Any) -> None:
309        """
310        Appends value to arg_key if it's a list or sets it as a new list.
311
312        Args:
313            arg_key (str): name of the list expression arg
314            value (Any): value to append to the list
315        """
316        if type(self.args.get(arg_key)) is not list:
317            self.args[arg_key] = []
318        self._set_parent(arg_key, value)
319        values = self.args[arg_key]
320        if hasattr(value, "parent"):
321            value.index = len(values)
322        values.append(value)
323
324    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
325        """
326        Sets arg_key to value.
327
328        Args:
329            arg_key: name of the expression arg.
330            value: value to set the arg to.
331            index: if the arg is a list, this specifies what position to add the value in it.
332        """
333        if index is not None:
334            expressions = self.args.get(arg_key) or []
335
336            if seq_get(expressions, index) is None:
337                return
338            if value is None:
339                expressions.pop(index)
340                for v in expressions[index:]:
341                    v.index = v.index - 1
342                return
343
344            if isinstance(value, list):
345                expressions.pop(index)
346                expressions[index:index] = value
347            else:
348                expressions[index] = value
349
350            value = expressions
351        elif value is None:
352            self.args.pop(arg_key, None)
353            return
354
355        self.args[arg_key] = value
356        self._set_parent(arg_key, value, index)
357
358    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
359        if hasattr(value, "parent"):
360            value.parent = self
361            value.arg_key = arg_key
362            value.index = index
363        elif type(value) is list:
364            for index, v in enumerate(value):
365                if hasattr(v, "parent"):
366                    v.parent = self
367                    v.arg_key = arg_key
368                    v.index = index
369
370    @property
371    def depth(self) -> int:
372        """
373        Returns the depth of this tree.
374        """
375        if self.parent:
376            return self.parent.depth + 1
377        return 0
378
379    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
380        """Yields the key and expression for all arguments, exploding list args."""
381        # remove tuple when python 3.7 is deprecated
382        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
383            if type(vs) is list:
384                for v in reversed(vs) if reverse else vs:
385                    if hasattr(v, "parent"):
386                        yield v
387            else:
388                if hasattr(vs, "parent"):
389                    yield vs
390
391    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
392        """
393        Returns the first node in this tree which matches at least one of
394        the specified types.
395
396        Args:
397            expression_types: the expression type(s) to match.
398            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
399
400        Returns:
401            The node which matches the criteria or None if no such node was found.
402        """
403        return next(self.find_all(*expression_types, bfs=bfs), None)
404
405    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
406        """
407        Returns a generator object which visits all nodes in this tree and only
408        yields those that match at least one of the specified expression types.
409
410        Args:
411            expression_types: the expression type(s) to match.
412            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
413
414        Returns:
415            The generator object.
416        """
417        for expression in self.walk(bfs=bfs):
418            if isinstance(expression, expression_types):
419                yield expression
420
421    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
422        """
423        Returns a nearest parent matching expression_types.
424
425        Args:
426            expression_types: the expression type(s) to match.
427
428        Returns:
429            The parent node.
430        """
431        ancestor = self.parent
432        while ancestor and not isinstance(ancestor, expression_types):
433            ancestor = ancestor.parent
434        return ancestor  # type: ignore
435
436    @property
437    def parent_select(self) -> t.Optional[Select]:
438        """
439        Returns the parent select statement.
440        """
441        return self.find_ancestor(Select)
442
443    @property
444    def same_parent(self) -> bool:
445        """Returns if the parent is the same class as itself."""
446        return type(self.parent) is self.__class__
447
448    def root(self) -> Expression:
449        """
450        Returns the root expression of this tree.
451        """
452        expression = self
453        while expression.parent:
454            expression = expression.parent
455        return expression
456
457    def walk(
458        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
459    ) -> t.Iterator[Expression]:
460        """
461        Returns a generator object which visits all nodes in this tree.
462
463        Args:
464            bfs (bool): if set to True the BFS traversal order will be applied,
465                otherwise the DFS traversal will be used instead.
466            prune ((node, parent, arg_key) -> bool): callable that returns True if
467                the generator should stop traversing this branch of the tree.
468
469        Returns:
470            the generator object.
471        """
472        if bfs:
473            yield from self.bfs(prune=prune)
474        else:
475            yield from self.dfs(prune=prune)
476
477    def dfs(
478        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
479    ) -> t.Iterator[Expression]:
480        """
481        Returns a generator object which visits all nodes in this tree in
482        the DFS (Depth-first) order.
483
484        Returns:
485            The generator object.
486        """
487        stack = [self]
488
489        while stack:
490            node = stack.pop()
491
492            yield node
493
494            if prune and prune(node):
495                continue
496
497            for v in node.iter_expressions(reverse=True):
498                stack.append(v)
499
500    def bfs(
501        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
502    ) -> t.Iterator[Expression]:
503        """
504        Returns a generator object which visits all nodes in this tree in
505        the BFS (Breadth-first) order.
506
507        Returns:
508            The generator object.
509        """
510        queue = deque([self])
511
512        while queue:
513            node = queue.popleft()
514
515            yield node
516
517            if prune and prune(node):
518                continue
519
520            for v in node.iter_expressions():
521                queue.append(v)
522
523    def unnest(self):
524        """
525        Returns the first non parenthesis child or self.
526        """
527        expression = self
528        while type(expression) is Paren:
529            expression = expression.this
530        return expression
531
532    def unalias(self):
533        """
534        Returns the inner expression if this is an Alias.
535        """
536        if isinstance(self, Alias):
537            return self.this
538        return self
539
540    def unnest_operands(self):
541        """
542        Returns unnested operands as a tuple.
543        """
544        return tuple(arg.unnest() for arg in self.iter_expressions())
545
546    def flatten(self, unnest=True):
547        """
548        Returns a generator which yields child nodes whose parents are the same class.
549
550        A AND B AND C -> [A, B, C]
551        """
552        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
553            if type(node) is not self.__class__:
554                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
555
556    def __str__(self) -> str:
557        return self.sql()
558
559    def __repr__(self) -> str:
560        return _to_s(self)
561
562    def to_s(self) -> str:
563        """
564        Same as __repr__, but includes additional information which can be useful
565        for debugging, like empty or missing args and the AST nodes' object IDs.
566        """
567        return _to_s(self, verbose=True)
568
569    def sql(self, dialect: DialectType = None, **opts) -> str:
570        """
571        Returns SQL string representation of this tree.
572
573        Args:
574            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
575            opts: other `sqlglot.generator.Generator` options.
576
577        Returns:
578            The SQL string.
579        """
580        from sqlglot.dialects import Dialect
581
582        return Dialect.get_or_raise(dialect).generate(self, **opts)
583
584    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
585        """
586        Visits all tree nodes (excluding already transformed ones)
587        and applies the given transformation function to each node.
588
589        Args:
590            fun (function): a function which takes a node as an argument and returns a
591                new transformed node or the same node without modifications. If the function
592                returns None, then the corresponding node will be removed from the syntax tree.
593            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
594                modified in place.
595
596        Returns:
597            The transformed tree.
598        """
599        root = None
600        new_node = None
601
602        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
603            parent, arg_key, index = node.parent, node.arg_key, node.index
604            new_node = fun(node, *args, **kwargs)
605
606            if not root:
607                root = new_node
608            elif new_node is not node:
609                parent.set(arg_key, new_node, index)
610
611        assert root
612        return root.assert_is(Expression)
613
614    @t.overload
615    def replace(self, expression: E) -> E: ...
616
617    @t.overload
618    def replace(self, expression: None) -> None: ...
619
620    def replace(self, expression):
621        """
622        Swap out this expression with a new expression.
623
624        For example::
625
626            >>> tree = Select().select("x").from_("tbl")
627            >>> tree.find(Column).replace(column("y"))
628            Column(
629              this=Identifier(this=y, quoted=False))
630            >>> tree.sql()
631            'SELECT y FROM tbl'
632
633        Args:
634            expression: new node
635
636        Returns:
637            The new expression or expressions.
638        """
639        parent = self.parent
640
641        if not parent or parent is expression:
642            return expression
643
644        key = self.arg_key
645        value = parent.args.get(key)
646
647        if type(expression) is list and isinstance(value, Expression):
648            # We are trying to replace an Expression with a list, so it's assumed that
649            # the intention was to really replace the parent of this expression.
650            value.parent.replace(expression)
651        else:
652            parent.set(key, expression, self.index)
653
654        if expression is not self:
655            self.parent = None
656            self.arg_key = None
657            self.index = None
658
659        return expression
660
661    def pop(self: E) -> E:
662        """
663        Remove this expression from its AST.
664
665        Returns:
666            The popped expression.
667        """
668        self.replace(None)
669        return self
670
671    def assert_is(self, type_: t.Type[E]) -> E:
672        """
673        Assert that this `Expression` is an instance of `type_`.
674
675        If it is NOT an instance of `type_`, this raises an assertion error.
676        Otherwise, this returns this expression.
677
678        Examples:
679            This is useful for type security in chained expressions:
680
681            >>> import sqlglot
682            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
683            'SELECT x, z FROM y'
684        """
685        if not isinstance(self, type_):
686            raise AssertionError(f"{self} is not {type_}.")
687        return self
688
689    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
690        """
691        Checks if this expression is valid (e.g. all mandatory args are set).
692
693        Args:
694            args: a sequence of values that were used to instantiate a Func expression. This is used
695                to check that the provided arguments don't exceed the function argument limit.
696
697        Returns:
698            A list of error messages for all possible errors that were found.
699        """
700        errors: t.List[str] = []
701
702        for k in self.args:
703            if k not in self.arg_types:
704                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
705        for k, mandatory in self.arg_types.items():
706            v = self.args.get(k)
707            if mandatory and (v is None or (isinstance(v, list) and not v)):
708                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
709
710        if (
711            args
712            and isinstance(self, Func)
713            and len(args) > len(self.arg_types)
714            and not self.is_var_len_args
715        ):
716            errors.append(
717                f"The number of provided arguments ({len(args)}) is greater than "
718                f"the maximum number of supported arguments ({len(self.arg_types)})"
719            )
720
721        return errors
722
723    def dump(self):
724        """
725        Dump this Expression to a JSON-serializable dict.
726        """
727        from sqlglot.serde import dump
728
729        return dump(self)
730
731    @classmethod
732    def load(cls, obj):
733        """
734        Load a dict (as returned by `Expression.dump`) into an Expression instance.
735        """
736        from sqlglot.serde import load
737
738        return load(obj)
739
740    def and_(
741        self,
742        *expressions: t.Optional[ExpOrStr],
743        dialect: DialectType = None,
744        copy: bool = True,
745        **opts,
746    ) -> Condition:
747        """
748        AND this condition with one or multiple expressions.
749
750        Example:
751            >>> condition("x=1").and_("y=1").sql()
752            'x = 1 AND y = 1'
753
754        Args:
755            *expressions: the SQL code strings to parse.
756                If an `Expression` instance is passed, it will be used as-is.
757            dialect: the dialect used to parse the input expression.
758            copy: whether to copy the involved expressions (only applies to Expressions).
759            opts: other options to use to parse the input expressions.
760
761        Returns:
762            The new And condition.
763        """
764        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)
765
766    def or_(
767        self,
768        *expressions: t.Optional[ExpOrStr],
769        dialect: DialectType = None,
770        copy: bool = True,
771        **opts,
772    ) -> Condition:
773        """
774        OR this condition with one or multiple expressions.
775
776        Example:
777            >>> condition("x=1").or_("y=1").sql()
778            'x = 1 OR y = 1'
779
780        Args:
781            *expressions: the SQL code strings to parse.
782                If an `Expression` instance is passed, it will be used as-is.
783            dialect: the dialect used to parse the input expression.
784            copy: whether to copy the involved expressions (only applies to Expressions).
785            opts: other options to use to parse the input expressions.
786
787        Returns:
788            The new Or condition.
789        """
790        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)
791
792    def not_(self, copy: bool = True):
793        """
794        Wrap this condition with NOT.
795
796        Example:
797            >>> condition("x=1").not_().sql()
798            'NOT x = 1'
799
800        Args:
801            copy: whether to copy this object.
802
803        Returns:
804            The new Not instance.
805        """
806        return not_(self, copy=copy)
807
808    def as_(
809        self,
810        alias: str | Identifier,
811        quoted: t.Optional[bool] = None,
812        dialect: DialectType = None,
813        copy: bool = True,
814        **opts,
815    ) -> Alias:
816        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
817
818    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
819        this = self.copy()
820        other = convert(other, copy=True)
821        if not isinstance(this, klass) and not isinstance(other, klass):
822            this = _wrap(this, Binary)
823            other = _wrap(other, Binary)
824        if reverse:
825            return klass(this=other, expression=this)
826        return klass(this=this, expression=other)
827
828    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
829        return Bracket(
830            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
831        )
832
833    def __iter__(self) -> t.Iterator:
834        if "expressions" in self.arg_types:
835            return iter(self.args.get("expressions") or [])
836        # We define this because __getitem__ converts Expression into an iterable, which is
837        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
838        # See: https://peps.python.org/pep-0234/
839        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
840
841    def isin(
842        self,
843        *expressions: t.Any,
844        query: t.Optional[ExpOrStr] = None,
845        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
846        copy: bool = True,
847        **opts,
848    ) -> In:
849        return In(
850            this=maybe_copy(self, copy),
851            expressions=[convert(e, copy=copy) for e in expressions],
852            query=maybe_parse(query, copy=copy, **opts) if query else None,
853            unnest=(
854                Unnest(
855                    expressions=[
856                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
857                        for e in ensure_list(unnest)
858                    ]
859                )
860                if unnest
861                else None
862            ),
863        )
864
865    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
866        return Between(
867            this=maybe_copy(self, copy),
868            low=convert(low, copy=copy, **opts),
869            high=convert(high, copy=copy, **opts),
870        )
871
872    def is_(self, other: ExpOrStr) -> Is:
873        return self._binop(Is, other)
874
875    def like(self, other: ExpOrStr) -> Like:
876        return self._binop(Like, other)
877
878    def ilike(self, other: ExpOrStr) -> ILike:
879        return self._binop(ILike, other)
880
881    def eq(self, other: t.Any) -> EQ:
882        return self._binop(EQ, other)
883
884    def neq(self, other: t.Any) -> NEQ:
885        return self._binop(NEQ, other)
886
887    def rlike(self, other: ExpOrStr) -> RegexpLike:
888        return self._binop(RegexpLike, other)
889
890    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
891        div = self._binop(Div, other)
892        div.args["typed"] = typed
893        div.args["safe"] = safe
894        return div
895
896    def asc(self, nulls_first: bool = True) -> Ordered:
897        return Ordered(this=self.copy(), nulls_first=nulls_first)
898
899    def desc(self, nulls_first: bool = False) -> Ordered:
900        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
901
902    def __lt__(self, other: t.Any) -> LT:
903        return self._binop(LT, other)
904
905    def __le__(self, other: t.Any) -> LTE:
906        return self._binop(LTE, other)
907
908    def __gt__(self, other: t.Any) -> GT:
909        return self._binop(GT, other)
910
911    def __ge__(self, other: t.Any) -> GTE:
912        return self._binop(GTE, other)
913
914    def __add__(self, other: t.Any) -> Add:
915        return self._binop(Add, other)
916
917    def __radd__(self, other: t.Any) -> Add:
918        return self._binop(Add, other, reverse=True)
919
920    def __sub__(self, other: t.Any) -> Sub:
921        return self._binop(Sub, other)
922
923    def __rsub__(self, other: t.Any) -> Sub:
924        return self._binop(Sub, other, reverse=True)
925
926    def __mul__(self, other: t.Any) -> Mul:
927        return self._binop(Mul, other)
928
929    def __rmul__(self, other: t.Any) -> Mul:
930        return self._binop(Mul, other, reverse=True)
931
932    def __truediv__(self, other: t.Any) -> Div:
933        return self._binop(Div, other)
934
935    def __rtruediv__(self, other: t.Any) -> Div:
936        return self._binop(Div, other, reverse=True)
937
938    def __floordiv__(self, other: t.Any) -> IntDiv:
939        return self._binop(IntDiv, other)
940
941    def __rfloordiv__(self, other: t.Any) -> IntDiv:
942        return self._binop(IntDiv, other, reverse=True)
943
944    def __mod__(self, other: t.Any) -> Mod:
945        return self._binop(Mod, other)
946
947    def __rmod__(self, other: t.Any) -> Mod:
948        return self._binop(Mod, other, reverse=True)
949
950    def __pow__(self, other: t.Any) -> Pow:
951        return self._binop(Pow, other)
952
953    def __rpow__(self, other: t.Any) -> Pow:
954        return self._binop(Pow, other, reverse=True)
955
956    def __and__(self, other: t.Any) -> And:
957        return self._binop(And, other)
958
959    def __rand__(self, other: t.Any) -> And:
960        return self._binop(And, other, reverse=True)
961
962    def __or__(self, other: t.Any) -> Or:
963        return self._binop(Or, other)
964
965    def __ror__(self, other: t.Any) -> Or:
966        return self._binop(Or, other, reverse=True)
967
968    def __neg__(self) -> Neg:
969        return Neg(this=_wrap(self.copy(), Binary))
970
971    def __invert__(self) -> Not:
972        return not_(self.copy())

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • index: the index of an expression if it is inside of a list argument in its parent.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
100    def __init__(self, **args: t.Any):
101        self.args: t.Dict[str, t.Any] = args
102        self.parent: t.Optional[Expression] = None
103        self.arg_key: t.Optional[str] = None
104        self.index: t.Optional[int] = None
105        self.comments: t.Optional[t.List[str]] = None
106        self._type: t.Optional[DataType] = None
107        self._meta: t.Optional[t.Dict[str, t.Any]] = None
108        self._hash: t.Optional[int] = None
109
110        for arg_key, value in self.args.items():
111            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
116    @property
117    def hashable_args(self) -> t.Any:
118        return frozenset(
119            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
120            for k, v in self.args.items()
121            if not (v is None or v is False or (type(v) is list and not v))
122        )
this: Any
130    @property
131    def this(self) -> t.Any:
132        """
133        Retrieves the argument with key "this".
134        """
135        return self.args.get("this")

Retrieves the argument with key "this".

expression: Any
137    @property
138    def expression(self) -> t.Any:
139        """
140        Retrieves the argument with key "expression".
141        """
142        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
144    @property
145    def expressions(self) -> t.List[t.Any]:
146        """
147        Retrieves the argument with key "expressions".
148        """
149        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
151    def text(self, key) -> str:
152        """
153        Returns a textual representation of the argument corresponding to "key". This can only be used
154        for args that are strings or leaf Expression instances, such as identifiers and literals.
155        """
156        field = self.args.get(key)
157        if isinstance(field, str):
158            return field
159        if isinstance(field, (Identifier, Literal, Var)):
160            return field.this
161        if isinstance(field, (Star, Null)):
162            return field.name
163        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
165    @property
166    def is_string(self) -> bool:
167        """
168        Checks whether a Literal expression is a string.
169        """
170        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
172    @property
173    def is_number(self) -> bool:
174        """
175        Checks whether a Literal expression is a number.
176        """
177        return isinstance(self, Literal) and not self.args["is_string"]

Checks whether a Literal expression is a number.

is_int: bool
179    @property
180    def is_int(self) -> bool:
181        """
182        Checks whether a Literal expression is an integer.
183        """
184        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
186    @property
187    def is_star(self) -> bool:
188        """Checks whether an expression is a star."""
189        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
191    @property
192    def alias(self) -> str:
193        """
194        Returns the alias of the expression, or an empty string if it's not aliased.
195        """
196        if isinstance(self.args.get("alias"), TableAlias):
197            return self.args["alias"].name
198        return self.text("alias")

Returns the alias of the expression, or an empty string if it's not aliased.

alias_column_names: List[str]
200    @property
201    def alias_column_names(self) -> t.List[str]:
202        table_alias = self.args.get("alias")
203        if not table_alias:
204            return []
205        return [c.name for c in table_alias.args.get("columns") or []]
name: str
207    @property
208    def name(self) -> str:
209        return self.text("this")
alias_or_name: str
211    @property
212    def alias_or_name(self) -> str:
213        return self.alias or self.name
output_name: str
215    @property
216    def output_name(self) -> str:
217        """
218        Name of the output column if this expression is a selection.
219
220        If the Expression has no output name, an empty string is returned.
221
222        Example:
223            >>> from sqlglot import parse_one
224            >>> parse_one("SELECT a").expressions[0].output_name
225            'a'
226            >>> parse_one("SELECT b AS c").expressions[0].output_name
227            'c'
228            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
229            ''
230        """
231        return ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
233    @property
234    def type(self) -> t.Optional[DataType]:
235        return self._type
def is_type(self, *dtypes) -> bool:
243    def is_type(self, *dtypes) -> bool:
244        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
246    def is_leaf(self) -> bool:
247        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
249    @property
250    def meta(self) -> t.Dict[str, t.Any]:
251        if self._meta is None:
252            self._meta = {}
253        return self._meta
def copy(self):
289    def copy(self):
290        """
291        Returns a deep copy of the expression.
292        """
293        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
295    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
296        if self.comments is None:
297            self.comments = []
298        if comments:
299            for comment in comments:
300                _, *meta = comment.split(SQLGLOT_META)
301                if meta:
302                    for kv in "".join(meta).split(","):
303                        k, *v = kv.split("=")
304                        value = v[0].strip() if v else True
305                        self.meta[k.strip()] = value
306                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
308    def append(self, arg_key: str, value: t.Any) -> None:
309        """
310        Appends value to arg_key if it's a list or sets it as a new list.
311
312        Args:
313            arg_key (str): name of the list expression arg
314            value (Any): value to append to the list
315        """
316        if type(self.args.get(arg_key)) is not list:
317            self.args[arg_key] = []
318        self._set_parent(arg_key, value)
319        values = self.args[arg_key]
320        if hasattr(value, "parent"):
321            value.index = len(values)
322        values.append(value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any, index: Optional[int] = None) -> None:
324    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
325        """
326        Sets arg_key to value.
327
328        Args:
329            arg_key: name of the expression arg.
330            value: value to set the arg to.
331            index: if the arg is a list, this specifies what position to add the value in it.
332        """
333        if index is not None:
334            expressions = self.args.get(arg_key) or []
335
336            if seq_get(expressions, index) is None:
337                return
338            if value is None:
339                expressions.pop(index)
340                for v in expressions[index:]:
341                    v.index = v.index - 1
342                return
343
344            if isinstance(value, list):
345                expressions.pop(index)
346                expressions[index:index] = value
347            else:
348                expressions[index] = value
349
350            value = expressions
351        elif value is None:
352            self.args.pop(arg_key, None)
353            return
354
355        self.args[arg_key] = value
356        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
depth: int
370    @property
371    def depth(self) -> int:
372        """
373        Returns the depth of this tree.
374        """
375        if self.parent:
376            return self.parent.depth + 1
377        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
379    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
380        """Yields the key and expression for all arguments, exploding list args."""
381        # remove tuple when python 3.7 is deprecated
382        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
383            if type(vs) is list:
384                for v in reversed(vs) if reverse else vs:
385                    if hasattr(v, "parent"):
386                        yield v
387            else:
388                if hasattr(vs, "parent"):
389                    yield vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
391    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
392        """
393        Returns the first node in this tree which matches at least one of
394        the specified types.
395
396        Args:
397            expression_types: the expression type(s) to match.
398            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
399
400        Returns:
401            The node which matches the criteria or None if no such node was found.
402        """
403        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
405    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
406        """
407        Returns a generator object which visits all nodes in this tree and only
408        yields those that match at least one of the specified expression types.
409
410        Args:
411            expression_types: the expression type(s) to match.
412            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
413
414        Returns:
415            The generator object.
416        """
417        for expression in self.walk(bfs=bfs):
418            if isinstance(expression, expression_types):
419                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
421    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
422        """
423        Returns a nearest parent matching expression_types.
424
425        Args:
426            expression_types: the expression type(s) to match.
427
428        Returns:
429            The parent node.
430        """
431        ancestor = self.parent
432        while ancestor and not isinstance(ancestor, expression_types):
433            ancestor = ancestor.parent
434        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
436    @property
437    def parent_select(self) -> t.Optional[Select]:
438        """
439        Returns the parent select statement.
440        """
441        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
443    @property
444    def same_parent(self) -> bool:
445        """Returns if the parent is the same class as itself."""
446        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
448    def root(self) -> Expression:
449        """
450        Returns the root expression of this tree.
451        """
452        expression = self
453        while expression.parent:
454            expression = expression.parent
455        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
457    def walk(
458        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
459    ) -> t.Iterator[Expression]:
460        """
461        Returns a generator object which visits all nodes in this tree.
462
463        Args:
464            bfs (bool): if set to True the BFS traversal order will be applied,
465                otherwise the DFS traversal will be used instead.
466            prune ((node, parent, arg_key) -> bool): callable that returns True if
467                the generator should stop traversing this branch of the tree.
468
469        Returns:
470            the generator object.
471        """
472        if bfs:
473            yield from self.bfs(prune=prune)
474        else:
475            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs (bool): if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune ((node, parent, arg_key) -> bool): callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
477    def dfs(
478        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
479    ) -> t.Iterator[Expression]:
480        """
481        Returns a generator object which visits all nodes in this tree in
482        the DFS (Depth-first) order.
483
484        Returns:
485            The generator object.
486        """
487        stack = [self]
488
489        while stack:
490            node = stack.pop()
491
492            yield node
493
494            if prune and prune(node):
495                continue
496
497            for v in node.iter_expressions(reverse=True):
498                stack.append(v)

Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.

Returns:

The generator object.

def bfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
500    def bfs(
501        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
502    ) -> t.Iterator[Expression]:
503        """
504        Returns a generator object which visits all nodes in this tree in
505        the BFS (Breadth-first) order.
506
507        Returns:
508            The generator object.
509        """
510        queue = deque([self])
511
512        while queue:
513            node = queue.popleft()
514
515            yield node
516
517            if prune and prune(node):
518                continue
519
520            for v in node.iter_expressions():
521                queue.append(v)

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
523    def unnest(self):
524        """
525        Returns the first non parenthesis child or self.
526        """
527        expression = self
528        while type(expression) is Paren:
529            expression = expression.this
530        return expression

Returns the first non parenthesis child or self.

def unalias(self):
532    def unalias(self):
533        """
534        Returns the inner expression if this is an Alias.
535        """
536        if isinstance(self, Alias):
537            return self.this
538        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
540    def unnest_operands(self):
541        """
542        Returns unnested operands as a tuple.
543        """
544        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
546    def flatten(self, unnest=True):
547        """
548        Returns a generator which yields child nodes whose parents are the same class.
549
550        A AND B AND C -> [A, B, C]
551        """
552        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
553            if type(node) is not self.__class__:
554                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
562    def to_s(self) -> str:
563        """
564        Same as __repr__, but includes additional information which can be useful
565        for debugging, like empty or missing args and the AST nodes' object IDs.
566        """
567        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
569    def sql(self, dialect: DialectType = None, **opts) -> str:
570        """
571        Returns SQL string representation of this tree.
572
573        Args:
574            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
575            opts: other `sqlglot.generator.Generator` options.
576
577        Returns:
578            The SQL string.
579        """
580        from sqlglot.dialects import Dialect
581
582        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

def transform( self, fun: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
584    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
585        """
586        Visits all tree nodes (excluding already transformed ones)
587        and applies the given transformation function to each node.
588
589        Args:
590            fun (function): a function which takes a node as an argument and returns a
591                new transformed node or the same node without modifications. If the function
592                returns None, then the corresponding node will be removed from the syntax tree.
593            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
594                modified in place.
595
596        Returns:
597            The transformed tree.
598        """
599        root = None
600        new_node = None
601
602        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
603            parent, arg_key, index = node.parent, node.arg_key, node.index
604            new_node = fun(node, *args, **kwargs)
605
606            if not root:
607                root = new_node
608            elif new_node is not node:
609                parent.set(arg_key, new_node, index)
610
611        assert root
612        return root.assert_is(Expression)

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun (function): a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy (bool): if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

def replace(self, expression):
620    def replace(self, expression):
621        """
622        Swap out this expression with a new expression.
623
624        For example::
625
626            >>> tree = Select().select("x").from_("tbl")
627            >>> tree.find(Column).replace(column("y"))
628            Column(
629              this=Identifier(this=y, quoted=False))
630            >>> tree.sql()
631            'SELECT y FROM tbl'
632
633        Args:
634            expression: new node
635
636        Returns:
637            The new expression or expressions.
638        """
639        parent = self.parent
640
641        if not parent or parent is expression:
642            return expression
643
644        key = self.arg_key
645        value = parent.args.get(key)
646
647        if type(expression) is list and isinstance(value, Expression):
648            # We are trying to replace an Expression with a list, so it's assumed that
649            # the intention was to really replace the parent of this expression.
650            value.parent.replace(expression)
651        else:
652            parent.set(key, expression, self.index)
653
654        if expression is not self:
655            self.parent = None
656            self.arg_key = None
657            self.index = None
658
659        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
661    def pop(self: E) -> E:
662        """
663        Remove this expression from its AST.
664
665        Returns:
666            The popped expression.
667        """
668        self.replace(None)
669        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
671    def assert_is(self, type_: t.Type[E]) -> E:
672        """
673        Assert that this `Expression` is an instance of `type_`.
674
675        If it is NOT an instance of `type_`, this raises an assertion error.
676        Otherwise, this returns this expression.
677
678        Examples:
679            This is useful for type security in chained expressions:
680
681            >>> import sqlglot
682            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
683            'SELECT x, z FROM y'
684        """
685        if not isinstance(self, type_):
686            raise AssertionError(f"{self} is not {type_}.")
687        return self

Assert that this Expression is an instance of type_.

If it is NOT an instance of type_, this raises an assertion error. Otherwise, this returns this expression.

Examples:

This is useful for type security in chained expressions:

>>> import sqlglot
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
689    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
690        """
691        Checks if this expression is valid (e.g. all mandatory args are set).
692
693        Args:
694            args: a sequence of values that were used to instantiate a Func expression. This is used
695                to check that the provided arguments don't exceed the function argument limit.
696
697        Returns:
698            A list of error messages for all possible errors that were found.
699        """
700        errors: t.List[str] = []
701
702        for k in self.args:
703            if k not in self.arg_types:
704                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
705        for k, mandatory in self.arg_types.items():
706            v = self.args.get(k)
707            if mandatory and (v is None or (isinstance(v, list) and not v)):
708                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
709
710        if (
711            args
712            and isinstance(self, Func)
713            and len(args) > len(self.arg_types)
714            and not self.is_var_len_args
715        ):
716            errors.append(
717                f"The number of provided arguments ({len(args)}) is greater than "
718                f"the maximum number of supported arguments ({len(self.arg_types)})"
719            )
720
721        return errors

Checks if this expression is valid (e.g. all mandatory args are set).

Arguments:
  • args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:

A list of error messages for all possible errors that were found.

def dump(self):
723    def dump(self):
724        """
725        Dump this Expression to a JSON-serializable dict.
726        """
727        from sqlglot.serde import dump
728
729        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
731    @classmethod
732    def load(cls, obj):
733        """
734        Load a dict (as returned by `Expression.dump`) into an Expression instance.
735        """
736        from sqlglot.serde import load
737
738        return load(obj)

Load a dict (as returned by Expression.dump) into an Expression instance.

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
740    def and_(
741        self,
742        *expressions: t.Optional[ExpOrStr],
743        dialect: DialectType = None,
744        copy: bool = True,
745        **opts,
746    ) -> Condition:
747        """
748        AND this condition with one or multiple expressions.
749
750        Example:
751            >>> condition("x=1").and_("y=1").sql()
752            'x = 1 AND y = 1'
753
754        Args:
755            *expressions: the SQL code strings to parse.
756                If an `Expression` instance is passed, it will be used as-is.
757            dialect: the dialect used to parse the input expression.
758            copy: whether to copy the involved expressions (only applies to Expressions).
759            opts: other options to use to parse the input expressions.
760
761        Returns:
762            The new And condition.
763        """
764        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1").and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
766    def or_(
767        self,
768        *expressions: t.Optional[ExpOrStr],
769        dialect: DialectType = None,
770        copy: bool = True,
771        **opts,
772    ) -> Condition:
773        """
774        OR this condition with one or multiple expressions.
775
776        Example:
777            >>> condition("x=1").or_("y=1").sql()
778            'x = 1 OR y = 1'
779
780        Args:
781            *expressions: the SQL code strings to parse.
782                If an `Expression` instance is passed, it will be used as-is.
783            dialect: the dialect used to parse the input expression.
784            copy: whether to copy the involved expressions (only applies to Expressions).
785            opts: other options to use to parse the input expressions.
786
787        Returns:
788            The new Or condition.
789        """
790        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1").or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
792    def not_(self, copy: bool = True):
793        """
794        Wrap this condition with NOT.
795
796        Example:
797            >>> condition("x=1").not_().sql()
798            'NOT x = 1'
799
800        Args:
801            copy: whether to copy this object.
802
803        Returns:
804            The new Not instance.
805        """
806        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether to copy this object.
Returns:

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
808    def as_(
809        self,
810        alias: str | Identifier,
811        quoted: t.Optional[bool] = None,
812        dialect: DialectType = None,
813        copy: bool = True,
814        **opts,
815    ) -> Alias:
816        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
841    def isin(
842        self,
843        *expressions: t.Any,
844        query: t.Optional[ExpOrStr] = None,
845        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
846        copy: bool = True,
847        **opts,
848    ) -> In:
849        return In(
850            this=maybe_copy(self, copy),
851            expressions=[convert(e, copy=copy) for e in expressions],
852            query=maybe_parse(query, copy=copy, **opts) if query else None,
853            unnest=(
854                Unnest(
855                    expressions=[
856                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
857                        for e in ensure_list(unnest)
858                    ]
859                )
860                if unnest
861                else None
862            ),
863        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
865    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
866        return Between(
867            this=maybe_copy(self, copy),
868            low=convert(low, copy=copy, **opts),
869            high=convert(high, copy=copy, **opts),
870        )
def is_( self, other: Union[str, Expression]) -> Is:
872    def is_(self, other: ExpOrStr) -> Is:
873        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
875    def like(self, other: ExpOrStr) -> Like:
876        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
878    def ilike(self, other: ExpOrStr) -> ILike:
879        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
881    def eq(self, other: t.Any) -> EQ:
882        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
884    def neq(self, other: t.Any) -> NEQ:
885        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
887    def rlike(self, other: ExpOrStr) -> RegexpLike:
888        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
890    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
891        div = self._binop(Div, other)
892        div.args["typed"] = typed
893        div.args["safe"] = safe
894        return div
def asc(self, nulls_first: bool = True) -> Ordered:
896    def asc(self, nulls_first: bool = True) -> Ordered:
897        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
899    def desc(self, nulls_first: bool = False) -> Ordered:
900        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
983class Condition(Expression):
984    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

key = 'condition'
class Predicate(Condition):
987class Predicate(Condition):
988    """Relationships like x = y, x > 1, x >= y."""

Relationships like x = y, x > 1, x >= y.

key = 'predicate'
class DerivedTable(Expression):
991class DerivedTable(Expression):
992    @property
993    def selects(self) -> t.List[Expression]:
994        return self.this.selects if isinstance(self.this, Query) else []
995
996    @property
997    def named_selects(self) -> t.List[str]:
998        return [select.output_name for select in self.selects]
selects: List[Expression]
992    @property
993    def selects(self) -> t.List[Expression]:
994        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
996    @property
997    def named_selects(self) -> t.List[str]:
998        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1001class Query(Expression):
1002    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1003        """
1004        Returns a `Subquery` that wraps around this query.
1005
1006        Example:
1007            >>> subquery = Select().select("x").from_("tbl").subquery()
1008            >>> Select().select("x").from_(subquery).sql()
1009            'SELECT x FROM (SELECT x FROM tbl)'
1010
1011        Args:
1012            alias: an optional alias for the subquery.
1013            copy: if `False`, modify this expression instance in-place.
1014        """
1015        instance = maybe_copy(self, copy)
1016        if not isinstance(alias, Expression):
1017            alias = TableAlias(this=to_identifier(alias)) if alias else None
1018
1019        return Subquery(this=instance, alias=alias)
1020
1021    def limit(
1022        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1023    ) -> Select:
1024        """
1025        Adds a LIMIT clause to this query.
1026
1027        Example:
1028            >>> select("1").union(select("1")).limit(1).sql()
1029            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1030
1031        Args:
1032            expression: the SQL code string to parse.
1033                This can also be an integer.
1034                If a `Limit` instance is passed, it will be used as-is.
1035                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1036            dialect: the dialect used to parse the input expression.
1037            copy: if `False`, modify this expression instance in-place.
1038            opts: other options to use to parse the input expressions.
1039
1040        Returns:
1041            A limited Select expression.
1042        """
1043        return (
1044            select("*")
1045            .from_(self.subquery(alias="_l_0", copy=copy))
1046            .limit(expression, dialect=dialect, copy=False, **opts)
1047        )
1048
1049    @property
1050    def ctes(self) -> t.List[CTE]:
1051        """Returns a list of all the CTEs attached to this query."""
1052        with_ = self.args.get("with")
1053        return with_.expressions if with_ else []
1054
1055    @property
1056    def selects(self) -> t.List[Expression]:
1057        """Returns the query's projections."""
1058        raise NotImplementedError("Query objects must implement `selects`")
1059
1060    @property
1061    def named_selects(self) -> t.List[str]:
1062        """Returns the output names of the query's projections."""
1063        raise NotImplementedError("Query objects must implement `named_selects`")
1064
1065    def select(
1066        self: Q,
1067        *expressions: t.Optional[ExpOrStr],
1068        append: bool = True,
1069        dialect: DialectType = None,
1070        copy: bool = True,
1071        **opts,
1072    ) -> Q:
1073        """
1074        Append to or set the SELECT expressions.
1075
1076        Example:
1077            >>> Select().select("x", "y").sql()
1078            'SELECT x, y'
1079
1080        Args:
1081            *expressions: the SQL code strings to parse.
1082                If an `Expression` instance is passed, it will be used as-is.
1083            append: if `True`, add to any existing expressions.
1084                Otherwise, this resets the expressions.
1085            dialect: the dialect used to parse the input expressions.
1086            copy: if `False`, modify this expression instance in-place.
1087            opts: other options to use to parse the input expressions.
1088
1089        Returns:
1090            The modified Query expression.
1091        """
1092        raise NotImplementedError("Query objects must implement `select`")
1093
1094    def with_(
1095        self: Q,
1096        alias: ExpOrStr,
1097        as_: ExpOrStr,
1098        recursive: t.Optional[bool] = None,
1099        append: bool = True,
1100        dialect: DialectType = None,
1101        copy: bool = True,
1102        **opts,
1103    ) -> Q:
1104        """
1105        Append to or set the common table expressions.
1106
1107        Example:
1108            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1109            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1110
1111        Args:
1112            alias: the SQL code string to parse as the table name.
1113                If an `Expression` instance is passed, this is used as-is.
1114            as_: the SQL code string to parse as the table expression.
1115                If an `Expression` instance is passed, it will be used as-is.
1116            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1117            append: if `True`, add to any existing expressions.
1118                Otherwise, this resets the expressions.
1119            dialect: the dialect used to parse the input expression.
1120            copy: if `False`, modify this expression instance in-place.
1121            opts: other options to use to parse the input expressions.
1122
1123        Returns:
1124            The modified expression.
1125        """
1126        return _apply_cte_builder(
1127            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1128        )
1129
1130    def union(
1131        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1132    ) -> Union:
1133        """
1134        Builds a UNION expression.
1135
1136        Example:
1137            >>> import sqlglot
1138            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1139            'SELECT * FROM foo UNION SELECT * FROM bla'
1140
1141        Args:
1142            expression: the SQL code string.
1143                If an `Expression` instance is passed, it will be used as-is.
1144            distinct: set the DISTINCT flag if and only if this is true.
1145            dialect: the dialect used to parse the input expression.
1146            opts: other options to use to parse the input expressions.
1147
1148        Returns:
1149            The new Union expression.
1150        """
1151        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1152
1153    def intersect(
1154        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1155    ) -> Intersect:
1156        """
1157        Builds an INTERSECT expression.
1158
1159        Example:
1160            >>> import sqlglot
1161            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1162            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1163
1164        Args:
1165            expression: the SQL code string.
1166                If an `Expression` instance is passed, it will be used as-is.
1167            distinct: set the DISTINCT flag if and only if this is true.
1168            dialect: the dialect used to parse the input expression.
1169            opts: other options to use to parse the input expressions.
1170
1171        Returns:
1172            The new Intersect expression.
1173        """
1174        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1175
1176    def except_(
1177        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1178    ) -> Except:
1179        """
1180        Builds an EXCEPT expression.
1181
1182        Example:
1183            >>> import sqlglot
1184            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1185            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1186
1187        Args:
1188            expression: the SQL code string.
1189                If an `Expression` instance is passed, it will be used as-is.
1190            distinct: set the DISTINCT flag if and only if this is true.
1191            dialect: the dialect used to parse the input expression.
1192            opts: other options to use to parse the input expressions.
1193
1194        Returns:
1195            The new Except expression.
1196        """
1197        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1002    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1003        """
1004        Returns a `Subquery` that wraps around this query.
1005
1006        Example:
1007            >>> subquery = Select().select("x").from_("tbl").subquery()
1008            >>> Select().select("x").from_(subquery).sql()
1009            'SELECT x FROM (SELECT x FROM tbl)'
1010
1011        Args:
1012            alias: an optional alias for the subquery.
1013            copy: if `False`, modify this expression instance in-place.
1014        """
1015        instance = maybe_copy(self, copy)
1016        if not isinstance(alias, Expression):
1017            alias = TableAlias(this=to_identifier(alias)) if alias else None
1018
1019        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
1021    def limit(
1022        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1023    ) -> Select:
1024        """
1025        Adds a LIMIT clause to this query.
1026
1027        Example:
1028            >>> select("1").union(select("1")).limit(1).sql()
1029            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1030
1031        Args:
1032            expression: the SQL code string to parse.
1033                This can also be an integer.
1034                If a `Limit` instance is passed, it will be used as-is.
1035                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1036            dialect: the dialect used to parse the input expression.
1037            copy: if `False`, modify this expression instance in-place.
1038            opts: other options to use to parse the input expressions.
1039
1040        Returns:
1041            A limited Select expression.
1042        """
1043        return (
1044            select("*")
1045            .from_(self.subquery(alias="_l_0", copy=copy))
1046            .limit(expression, dialect=dialect, copy=False, **opts)
1047        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

ctes: List[CTE]
1049    @property
1050    def ctes(self) -> t.List[CTE]:
1051        """Returns a list of all the CTEs attached to this query."""
1052        with_ = self.args.get("with")
1053        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this query.

selects: List[Expression]
1055    @property
1056    def selects(self) -> t.List[Expression]:
1057        """Returns the query's projections."""
1058        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1060    @property
1061    def named_selects(self) -> t.List[str]:
1062        """Returns the output names of the query's projections."""
1063        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1065    def select(
1066        self: Q,
1067        *expressions: t.Optional[ExpOrStr],
1068        append: bool = True,
1069        dialect: DialectType = None,
1070        copy: bool = True,
1071        **opts,
1072    ) -> Q:
1073        """
1074        Append to or set the SELECT expressions.
1075
1076        Example:
1077            >>> Select().select("x", "y").sql()
1078            'SELECT x, y'
1079
1080        Args:
1081            *expressions: the SQL code strings to parse.
1082                If an `Expression` instance is passed, it will be used as-is.
1083            append: if `True`, add to any existing expressions.
1084                Otherwise, this resets the expressions.
1085            dialect: the dialect used to parse the input expressions.
1086            copy: if `False`, modify this expression instance in-place.
1087            opts: other options to use to parse the input expressions.
1088
1089        Returns:
1090            The modified Query expression.
1091        """
1092        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1094    def with_(
1095        self: Q,
1096        alias: ExpOrStr,
1097        as_: ExpOrStr,
1098        recursive: t.Optional[bool] = None,
1099        append: bool = True,
1100        dialect: DialectType = None,
1101        copy: bool = True,
1102        **opts,
1103    ) -> Q:
1104        """
1105        Append to or set the common table expressions.
1106
1107        Example:
1108            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1109            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1110
1111        Args:
1112            alias: the SQL code string to parse as the table name.
1113                If an `Expression` instance is passed, this is used as-is.
1114            as_: the SQL code string to parse as the table expression.
1115                If an `Expression` instance is passed, it will be used as-is.
1116            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1117            append: if `True`, add to any existing expressions.
1118                Otherwise, this resets the expressions.
1119            dialect: the dialect used to parse the input expression.
1120            copy: if `False`, modify this expression instance in-place.
1121            opts: other options to use to parse the input expressions.
1122
1123        Returns:
1124            The modified expression.
1125        """
1126        return _apply_cte_builder(
1127            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1128        )

Append to or set the common table expressions.

Example:
>>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1130    def union(
1131        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1132    ) -> Union:
1133        """
1134        Builds a UNION expression.
1135
1136        Example:
1137            >>> import sqlglot
1138            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1139            'SELECT * FROM foo UNION SELECT * FROM bla'
1140
1141        Args:
1142            expression: the SQL code string.
1143                If an `Expression` instance is passed, it will be used as-is.
1144            distinct: set the DISTINCT flag if and only if this is true.
1145            dialect: the dialect used to parse the input expression.
1146            opts: other options to use to parse the input expressions.
1147
1148        Returns:
1149            The new Union expression.
1150        """
1151        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union expression.

def intersect( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1153    def intersect(
1154        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1155    ) -> Intersect:
1156        """
1157        Builds an INTERSECT expression.
1158
1159        Example:
1160            >>> import sqlglot
1161            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1162            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1163
1164        Args:
1165            expression: the SQL code string.
1166                If an `Expression` instance is passed, it will be used as-is.
1167            distinct: set the DISTINCT flag if and only if this is true.
1168            dialect: the dialect used to parse the input expression.
1169            opts: other options to use to parse the input expressions.
1170
1171        Returns:
1172            The new Intersect expression.
1173        """
1174        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect expression.

def except_( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1176    def except_(
1177        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1178    ) -> Except:
1179        """
1180        Builds an EXCEPT expression.
1181
1182        Example:
1183            >>> import sqlglot
1184            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1185            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1186
1187        Args:
1188            expression: the SQL code string.
1189                If an `Expression` instance is passed, it will be used as-is.
1190            distinct: set the DISTINCT flag if and only if this is true.
1191            dialect: the dialect used to parse the input expression.
1192            opts: other options to use to parse the input expressions.
1193
1194        Returns:
1195            The new Except expression.
1196        """
1197        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1200class UDTF(DerivedTable):
1201    @property
1202    def selects(self) -> t.List[Expression]:
1203        alias = self.args.get("alias")
1204        return alias.columns if alias else []
selects: List[Expression]
1201    @property
1202    def selects(self) -> t.List[Expression]:
1203        alias = self.args.get("alias")
1204        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1207class Cache(Expression):
1208    arg_types = {
1209        "this": True,
1210        "lazy": False,
1211        "options": False,
1212        "expression": False,
1213    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1216class Uncache(Expression):
1217    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1220class Refresh(Expression):
1221    pass
key = 'refresh'
class DDL(Expression):
1224class DDL(Expression):
1225    @property
1226    def ctes(self) -> t.List[CTE]:
1227        """Returns a list of all the CTEs attached to this statement."""
1228        with_ = self.args.get("with")
1229        return with_.expressions if with_ else []
1230
1231    @property
1232    def selects(self) -> t.List[Expression]:
1233        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1234        return self.expression.selects if isinstance(self.expression, Query) else []
1235
1236    @property
1237    def named_selects(self) -> t.List[str]:
1238        """
1239        If this statement contains a query (e.g. a CTAS), this returns the output
1240        names of the query's projections.
1241        """
1242        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1225    @property
1226    def ctes(self) -> t.List[CTE]:
1227        """Returns a list of all the CTEs attached to this statement."""
1228        with_ = self.args.get("with")
1229        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this statement.

selects: List[Expression]
1231    @property
1232    def selects(self) -> t.List[Expression]:
1233        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1234        return self.expression.selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the query's projections.

named_selects: List[str]
1236    @property
1237    def named_selects(self) -> t.List[str]:
1238        """
1239        If this statement contains a query (e.g. a CTAS), this returns the output
1240        names of the query's projections.
1241        """
1242        return self.expression.named_selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the output names of the query's projections.

key = 'ddl'
class DML(Expression):
1245class DML(Expression):
1246    def returning(
1247        self,
1248        expression: ExpOrStr,
1249        dialect: DialectType = None,
1250        copy: bool = True,
1251        **opts,
1252    ) -> DML:
1253        """
1254        Set the RETURNING expression. Not supported by all dialects.
1255
1256        Example:
1257            >>> delete("tbl").returning("*", dialect="postgres").sql()
1258            'DELETE FROM tbl RETURNING *'
1259
1260        Args:
1261            expression: the SQL code strings to parse.
1262                If an `Expression` instance is passed, it will be used as-is.
1263            dialect: the dialect used to parse the input expressions.
1264            copy: if `False`, modify this expression instance in-place.
1265            opts: other options to use to parse the input expressions.
1266
1267        Returns:
1268            Delete: the modified expression.
1269        """
1270        return _apply_builder(
1271            expression=expression,
1272            instance=self,
1273            arg="returning",
1274            prefix="RETURNING",
1275            dialect=dialect,
1276            copy=copy,
1277            into=Returning,
1278            **opts,
1279        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> DML:
1246    def returning(
1247        self,
1248        expression: ExpOrStr,
1249        dialect: DialectType = None,
1250        copy: bool = True,
1251        **opts,
1252    ) -> DML:
1253        """
1254        Set the RETURNING expression. Not supported by all dialects.
1255
1256        Example:
1257            >>> delete("tbl").returning("*", dialect="postgres").sql()
1258            'DELETE FROM tbl RETURNING *'
1259
1260        Args:
1261            expression: the SQL code strings to parse.
1262                If an `Expression` instance is passed, it will be used as-is.
1263            dialect: the dialect used to parse the input expressions.
1264            copy: if `False`, modify this expression instance in-place.
1265            opts: other options to use to parse the input expressions.
1266
1267        Returns:
1268            Delete: the modified expression.
1269        """
1270        return _apply_builder(
1271            expression=expression,
1272            instance=self,
1273            arg="returning",
1274            prefix="RETURNING",
1275            dialect=dialect,
1276            copy=copy,
1277            into=Returning,
1278            **opts,
1279        )

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1282class Create(DDL):
1283    arg_types = {
1284        "with": False,
1285        "this": True,
1286        "kind": True,
1287        "expression": False,
1288        "exists": False,
1289        "properties": False,
1290        "replace": False,
1291        "unique": False,
1292        "indexes": False,
1293        "no_schema_binding": False,
1294        "begin": False,
1295        "end": False,
1296        "clone": False,
1297    }
1298
1299    @property
1300    def kind(self) -> t.Optional[str]:
1301        kind = self.args.get("kind")
1302        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
kind: Optional[str]
1299    @property
1300    def kind(self) -> t.Optional[str]:
1301        kind = self.args.get("kind")
1302        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1305class SequenceProperties(Expression):
1306    arg_types = {
1307        "increment": False,
1308        "minvalue": False,
1309        "maxvalue": False,
1310        "cache": False,
1311        "start": False,
1312        "owned": False,
1313        "options": False,
1314    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1317class TruncateTable(Expression):
1318    arg_types = {
1319        "expressions": True,
1320        "is_database": False,
1321        "exists": False,
1322        "only": False,
1323        "cluster": False,
1324        "identity": False,
1325        "option": False,
1326        "partition": False,
1327    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1333class Clone(Expression):
1334    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1337class Describe(Expression):
1338    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1341class Kill(Expression):
1342    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1345class Pragma(Expression):
1346    pass
key = 'pragma'
class Set(Expression):
1349class Set(Expression):
1350    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1353class Heredoc(Expression):
1354    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1357class SetItem(Expression):
1358    arg_types = {
1359        "this": False,
1360        "expressions": False,
1361        "kind": False,
1362        "collate": False,  # MySQL SET NAMES statement
1363        "global": False,
1364    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1367class Show(Expression):
1368    arg_types = {
1369        "this": True,
1370        "history": False,
1371        "terse": False,
1372        "target": False,
1373        "offset": False,
1374        "starts_with": False,
1375        "limit": False,
1376        "from": False,
1377        "like": False,
1378        "where": False,
1379        "db": False,
1380        "scope": False,
1381        "scope_kind": False,
1382        "full": False,
1383        "mutex": False,
1384        "query": False,
1385        "channel": False,
1386        "global": False,
1387        "log": False,
1388        "position": False,
1389        "types": False,
1390    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1393class UserDefinedFunction(Expression):
1394    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1397class CharacterSet(Expression):
1398    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1401class With(Expression):
1402    arg_types = {"expressions": True, "recursive": False}
1403
1404    @property
1405    def recursive(self) -> bool:
1406        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1404    @property
1405    def recursive(self) -> bool:
1406        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1409class WithinGroup(Expression):
1410    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1415class CTE(DerivedTable):
1416    arg_types = {
1417        "this": True,
1418        "alias": True,
1419        "scalar": False,
1420        "materialized": False,
1421    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class TableAlias(Expression):
1424class TableAlias(Expression):
1425    arg_types = {"this": False, "columns": False}
1426
1427    @property
1428    def columns(self):
1429        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1427    @property
1428    def columns(self):
1429        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1432class BitString(Condition):
1433    pass
key = 'bitstring'
class HexString(Condition):
1436class HexString(Condition):
1437    pass
key = 'hexstring'
class ByteString(Condition):
1440class ByteString(Condition):
1441    pass
key = 'bytestring'
class RawString(Condition):
1444class RawString(Condition):
1445    pass
key = 'rawstring'
class UnicodeString(Condition):
1448class UnicodeString(Condition):
1449    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1452class Column(Condition):
1453    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1454
1455    @property
1456    def table(self) -> str:
1457        return self.text("table")
1458
1459    @property
1460    def db(self) -> str:
1461        return self.text("db")
1462
1463    @property
1464    def catalog(self) -> str:
1465        return self.text("catalog")
1466
1467    @property
1468    def output_name(self) -> str:
1469        return self.name
1470
1471    @property
1472    def parts(self) -> t.List[Identifier]:
1473        """Return the parts of a column in order catalog, db, table, name."""
1474        return [
1475            t.cast(Identifier, self.args[part])
1476            for part in ("catalog", "db", "table", "this")
1477            if self.args.get(part)
1478        ]
1479
1480    def to_dot(self) -> Dot | Identifier:
1481        """Converts the column into a dot expression."""
1482        parts = self.parts
1483        parent = self.parent
1484
1485        while parent:
1486            if isinstance(parent, Dot):
1487                parts.append(parent.expression)
1488            parent = parent.parent
1489
1490        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1455    @property
1456    def table(self) -> str:
1457        return self.text("table")
db: str
1459    @property
1460    def db(self) -> str:
1461        return self.text("db")
catalog: str
1463    @property
1464    def catalog(self) -> str:
1465        return self.text("catalog")
output_name: str
1467    @property
1468    def output_name(self) -> str:
1469        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1471    @property
1472    def parts(self) -> t.List[Identifier]:
1473        """Return the parts of a column in order catalog, db, table, name."""
1474        return [
1475            t.cast(Identifier, self.args[part])
1476            for part in ("catalog", "db", "table", "this")
1477            if self.args.get(part)
1478        ]

Return the parts of a column in order catalog, db, table, name.

def to_dot(self) -> Dot | Identifier:
1480    def to_dot(self) -> Dot | Identifier:
1481        """Converts the column into a dot expression."""
1482        parts = self.parts
1483        parent = self.parent
1484
1485        while parent:
1486            if isinstance(parent, Dot):
1487                parts.append(parent.expression)
1488            parent = parent.parent
1489
1490        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1493class ColumnPosition(Expression):
1494    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1497class ColumnDef(Expression):
1498    arg_types = {
1499        "this": True,
1500        "kind": False,
1501        "constraints": False,
1502        "exists": False,
1503        "position": False,
1504    }
1505
1506    @property
1507    def constraints(self) -> t.List[ColumnConstraint]:
1508        return self.args.get("constraints") or []
1509
1510    @property
1511    def kind(self) -> t.Optional[DataType]:
1512        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1506    @property
1507    def constraints(self) -> t.List[ColumnConstraint]:
1508        return self.args.get("constraints") or []
kind: Optional[DataType]
1510    @property
1511    def kind(self) -> t.Optional[DataType]:
1512        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1515class AlterColumn(Expression):
1516    arg_types = {
1517        "this": True,
1518        "dtype": False,
1519        "collate": False,
1520        "using": False,
1521        "default": False,
1522        "drop": False,
1523        "comment": False,
1524    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1527class RenameColumn(Expression):
1528    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1531class RenameTable(Expression):
1532    pass
key = 'renametable'
class SwapTable(Expression):
1535class SwapTable(Expression):
1536    pass
key = 'swaptable'
class Comment(Expression):
1539class Comment(Expression):
1540    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False}
key = 'comment'
class Comprehension(Expression):
1543class Comprehension(Expression):
1544    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
arg_types = {'this': True, 'expression': True, 'iterator': True, 'condition': False}
key = 'comprehension'
class MergeTreeTTLAction(Expression):
1548class MergeTreeTTLAction(Expression):
1549    arg_types = {
1550        "this": True,
1551        "delete": False,
1552        "recompress": False,
1553        "to_disk": False,
1554        "to_volume": False,
1555    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1559class MergeTreeTTL(Expression):
1560    arg_types = {
1561        "expressions": True,
1562        "where": False,
1563        "group": False,
1564        "aggregates": False,
1565    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1569class IndexConstraintOption(Expression):
1570    arg_types = {
1571        "key_block_size": False,
1572        "using": False,
1573        "parser": False,
1574        "comment": False,
1575        "visible": False,
1576        "engine_attr": False,
1577        "secondary_engine_attr": False,
1578    }
arg_types = {'key_block_size': False, 'using': False, 'parser': False, 'comment': False, 'visible': False, 'engine_attr': False, 'secondary_engine_attr': False}
key = 'indexconstraintoption'
class ColumnConstraint(Expression):
1581class ColumnConstraint(Expression):
1582    arg_types = {"this": False, "kind": True}
1583
1584    @property
1585    def kind(self) -> ColumnConstraintKind:
1586        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1584    @property
1585    def kind(self) -> ColumnConstraintKind:
1586        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1589class ColumnConstraintKind(Expression):
1590    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1593class AutoIncrementColumnConstraint(ColumnConstraintKind):
1594    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1597class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1598    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1601class CaseSpecificColumnConstraint(ColumnConstraintKind):
1602    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1605class CharacterSetColumnConstraint(ColumnConstraintKind):
1606    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1609class CheckColumnConstraint(ColumnConstraintKind):
1610    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1613class ClusteredColumnConstraint(ColumnConstraintKind):
1614    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1617class CollateColumnConstraint(ColumnConstraintKind):
1618    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1621class CommentColumnConstraint(ColumnConstraintKind):
1622    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1625class CompressColumnConstraint(ColumnConstraintKind):
1626    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1629class DateFormatColumnConstraint(ColumnConstraintKind):
1630    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1633class DefaultColumnConstraint(ColumnConstraintKind):
1634    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1637class EncodeColumnConstraint(ColumnConstraintKind):
1638    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1642class ExcludeColumnConstraint(ColumnConstraintKind):
1643    pass
key = 'excludecolumnconstraint'
class WithOperator(Expression):
1646class WithOperator(Expression):
1647    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1650class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1651    # this: True -> ALWAYS, this: False -> BY DEFAULT
1652    arg_types = {
1653        "this": False,
1654        "expression": False,
1655        "on_null": False,
1656        "start": False,
1657        "increment": False,
1658        "minvalue": False,
1659        "maxvalue": False,
1660        "cycle": False,
1661    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1664class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1665    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1669class IndexColumnConstraint(ColumnConstraintKind):
1670    arg_types = {
1671        "this": False,
1672        "schema": True,
1673        "kind": False,
1674        "index_type": False,
1675        "options": False,
1676    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1679class InlineLengthColumnConstraint(ColumnConstraintKind):
1680    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1683class NonClusteredColumnConstraint(ColumnConstraintKind):
1684    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1687class NotForReplicationColumnConstraint(ColumnConstraintKind):
1688    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1691class NotNullColumnConstraint(ColumnConstraintKind):
1692    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1696class OnUpdateColumnConstraint(ColumnConstraintKind):
1697    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1701class TransformColumnConstraint(ColumnConstraintKind):
1702    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1705class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1706    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1709class TitleColumnConstraint(ColumnConstraintKind):
1710    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1713class UniqueColumnConstraint(ColumnConstraintKind):
1714    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1717class UppercaseColumnConstraint(ColumnConstraintKind):
1718    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1721class PathColumnConstraint(ColumnConstraintKind):
1722    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1727class ComputedColumnConstraint(ColumnConstraintKind):
1728    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1731class Constraint(Expression):
1732    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1735class Delete(DML):
1736    arg_types = {
1737        "with": False,
1738        "this": False,
1739        "using": False,
1740        "where": False,
1741        "returning": False,
1742        "limit": False,
1743        "tables": False,  # Multiple-Table Syntax (MySQL)
1744    }
1745
1746    def delete(
1747        self,
1748        table: ExpOrStr,
1749        dialect: DialectType = None,
1750        copy: bool = True,
1751        **opts,
1752    ) -> Delete:
1753        """
1754        Create a DELETE expression or replace the table on an existing DELETE expression.
1755
1756        Example:
1757            >>> delete("tbl").sql()
1758            'DELETE FROM tbl'
1759
1760        Args:
1761            table: the table from which to delete.
1762            dialect: the dialect used to parse the input expression.
1763            copy: if `False`, modify this expression instance in-place.
1764            opts: other options to use to parse the input expressions.
1765
1766        Returns:
1767            Delete: the modified expression.
1768        """
1769        return _apply_builder(
1770            expression=table,
1771            instance=self,
1772            arg="this",
1773            dialect=dialect,
1774            into=Table,
1775            copy=copy,
1776            **opts,
1777        )
1778
1779    def where(
1780        self,
1781        *expressions: t.Optional[ExpOrStr],
1782        append: bool = True,
1783        dialect: DialectType = None,
1784        copy: bool = True,
1785        **opts,
1786    ) -> Delete:
1787        """
1788        Append to or set the WHERE expressions.
1789
1790        Example:
1791            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1792            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1793
1794        Args:
1795            *expressions: the SQL code strings to parse.
1796                If an `Expression` instance is passed, it will be used as-is.
1797                Multiple expressions are combined with an AND operator.
1798            append: if `True`, AND the new expressions to any existing expression.
1799                Otherwise, this resets the expression.
1800            dialect: the dialect used to parse the input expressions.
1801            copy: if `False`, modify this expression instance in-place.
1802            opts: other options to use to parse the input expressions.
1803
1804        Returns:
1805            Delete: the modified expression.
1806        """
1807        return _apply_conjunction_builder(
1808            *expressions,
1809            instance=self,
1810            arg="where",
1811            append=append,
1812            into=Where,
1813            dialect=dialect,
1814            copy=copy,
1815            **opts,
1816        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1746    def delete(
1747        self,
1748        table: ExpOrStr,
1749        dialect: DialectType = None,
1750        copy: bool = True,
1751        **opts,
1752    ) -> Delete:
1753        """
1754        Create a DELETE expression or replace the table on an existing DELETE expression.
1755
1756        Example:
1757            >>> delete("tbl").sql()
1758            'DELETE FROM tbl'
1759
1760        Args:
1761            table: the table from which to delete.
1762            dialect: the dialect used to parse the input expression.
1763            copy: if `False`, modify this expression instance in-place.
1764            opts: other options to use to parse the input expressions.
1765
1766        Returns:
1767            Delete: the modified expression.
1768        """
1769        return _apply_builder(
1770            expression=table,
1771            instance=self,
1772            arg="this",
1773            dialect=dialect,
1774            into=Table,
1775            copy=copy,
1776            **opts,
1777        )

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1779    def where(
1780        self,
1781        *expressions: t.Optional[ExpOrStr],
1782        append: bool = True,
1783        dialect: DialectType = None,
1784        copy: bool = True,
1785        **opts,
1786    ) -> Delete:
1787        """
1788        Append to or set the WHERE expressions.
1789
1790        Example:
1791            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1792            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1793
1794        Args:
1795            *expressions: the SQL code strings to parse.
1796                If an `Expression` instance is passed, it will be used as-is.
1797                Multiple expressions are combined with an AND operator.
1798            append: if `True`, AND the new expressions to any existing expression.
1799                Otherwise, this resets the expression.
1800            dialect: the dialect used to parse the input expressions.
1801            copy: if `False`, modify this expression instance in-place.
1802            opts: other options to use to parse the input expressions.
1803
1804        Returns:
1805            Delete: the modified expression.
1806        """
1807        return _apply_conjunction_builder(
1808            *expressions,
1809            instance=self,
1810            arg="where",
1811            append=append,
1812            into=Where,
1813            dialect=dialect,
1814            copy=copy,
1815            **opts,
1816        )

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
1819class Drop(Expression):
1820    arg_types = {
1821        "this": False,
1822        "kind": False,
1823        "expressions": False,
1824        "exists": False,
1825        "temporary": False,
1826        "materialized": False,
1827        "cascade": False,
1828        "constraints": False,
1829        "purge": False,
1830    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1833class Filter(Expression):
1834    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1837class Check(Expression):
1838    pass
key = 'check'
class Connect(Expression):
1842class Connect(Expression):
1843    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class Prior(Expression):
1846class Prior(Expression):
1847    pass
key = 'prior'
class Directory(Expression):
1850class Directory(Expression):
1851    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1852    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1855class ForeignKey(Expression):
1856    arg_types = {
1857        "expressions": True,
1858        "reference": False,
1859        "delete": False,
1860        "update": False,
1861    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1864class ColumnPrefix(Expression):
1865    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1868class PrimaryKey(Expression):
1869    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1874class Into(Expression):
1875    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1878class From(Expression):
1879    @property
1880    def name(self) -> str:
1881        return self.this.name
1882
1883    @property
1884    def alias_or_name(self) -> str:
1885        return self.this.alias_or_name
name: str
1879    @property
1880    def name(self) -> str:
1881        return self.this.name
alias_or_name: str
1883    @property
1884    def alias_or_name(self) -> str:
1885        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1888class Having(Expression):
1889    pass
key = 'having'
class Hint(Expression):
1892class Hint(Expression):
1893    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1896class JoinHint(Expression):
1897    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1900class Identifier(Expression):
1901    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1902
1903    @property
1904    def quoted(self) -> bool:
1905        return bool(self.args.get("quoted"))
1906
1907    @property
1908    def hashable_args(self) -> t.Any:
1909        return (self.this, self.quoted)
1910
1911    @property
1912    def output_name(self) -> str:
1913        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1903    @property
1904    def quoted(self) -> bool:
1905        return bool(self.args.get("quoted"))
hashable_args: Any
1907    @property
1908    def hashable_args(self) -> t.Any:
1909        return (self.this, self.quoted)
output_name: str
1911    @property
1912    def output_name(self) -> str:
1913        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
1917class Opclass(Expression):
1918    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1921class Index(Expression):
1922    arg_types = {
1923        "this": False,
1924        "table": False,
1925        "unique": False,
1926        "primary": False,
1927        "amp": False,  # teradata
1928        "params": False,
1929    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
1932class IndexParameters(Expression):
1933    arg_types = {
1934        "using": False,
1935        "include": False,
1936        "columns": False,
1937        "with_storage": False,
1938        "partition_by": False,
1939        "tablespace": False,
1940        "where": False,
1941    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
1944class Insert(DDL, DML):
1945    arg_types = {
1946        "hint": False,
1947        "with": False,
1948        "is_function": False,
1949        "this": True,
1950        "expression": False,
1951        "conflict": False,
1952        "returning": False,
1953        "overwrite": False,
1954        "exists": False,
1955        "partition": False,
1956        "alternative": False,
1957        "where": False,
1958        "ignore": False,
1959        "by_name": False,
1960    }
1961
1962    def with_(
1963        self,
1964        alias: ExpOrStr,
1965        as_: ExpOrStr,
1966        recursive: t.Optional[bool] = None,
1967        append: bool = True,
1968        dialect: DialectType = None,
1969        copy: bool = True,
1970        **opts,
1971    ) -> Insert:
1972        """
1973        Append to or set the common table expressions.
1974
1975        Example:
1976            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1977            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1978
1979        Args:
1980            alias: the SQL code string to parse as the table name.
1981                If an `Expression` instance is passed, this is used as-is.
1982            as_: the SQL code string to parse as the table expression.
1983                If an `Expression` instance is passed, it will be used as-is.
1984            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1985            append: if `True`, add to any existing expressions.
1986                Otherwise, this resets the expressions.
1987            dialect: the dialect used to parse the input expression.
1988            copy: if `False`, modify this expression instance in-place.
1989            opts: other options to use to parse the input expressions.
1990
1991        Returns:
1992            The modified expression.
1993        """
1994        return _apply_cte_builder(
1995            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1996        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
1962    def with_(
1963        self,
1964        alias: ExpOrStr,
1965        as_: ExpOrStr,
1966        recursive: t.Optional[bool] = None,
1967        append: bool = True,
1968        dialect: DialectType = None,
1969        copy: bool = True,
1970        **opts,
1971    ) -> Insert:
1972        """
1973        Append to or set the common table expressions.
1974
1975        Example:
1976            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1977            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1978
1979        Args:
1980            alias: the SQL code string to parse as the table name.
1981                If an `Expression` instance is passed, this is used as-is.
1982            as_: the SQL code string to parse as the table expression.
1983                If an `Expression` instance is passed, it will be used as-is.
1984            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1985            append: if `True`, add to any existing expressions.
1986                Otherwise, this resets the expressions.
1987            dialect: the dialect used to parse the input expression.
1988            copy: if `False`, modify this expression instance in-place.
1989            opts: other options to use to parse the input expressions.
1990
1991        Returns:
1992            The modified expression.
1993        """
1994        return _apply_cte_builder(
1995            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1996        )

Append to or set the common table expressions.

Example:
>>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'insert'
class OnConflict(Expression):
1999class OnConflict(Expression):
2000    arg_types = {
2001        "duplicate": False,
2002        "expressions": False,
2003        "action": False,
2004        "conflict_keys": False,
2005        "constraint": False,
2006    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2009class Returning(Expression):
2010    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2014class Introducer(Expression):
2015    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2019class National(Expression):
2020    pass
key = 'national'
class LoadData(Expression):
2023class LoadData(Expression):
2024    arg_types = {
2025        "this": True,
2026        "local": False,
2027        "overwrite": False,
2028        "inpath": True,
2029        "partition": False,
2030        "input_format": False,
2031        "serde": False,
2032    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2035class Partition(Expression):
2036    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2039class PartitionRange(Expression):
2040    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2043class Fetch(Expression):
2044    arg_types = {
2045        "direction": False,
2046        "count": False,
2047        "percent": False,
2048        "with_ties": False,
2049    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2052class Group(Expression):
2053    arg_types = {
2054        "expressions": False,
2055        "grouping_sets": False,
2056        "cube": False,
2057        "rollup": False,
2058        "totals": False,
2059        "all": False,
2060    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2063class Lambda(Expression):
2064    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2067class Limit(Expression):
2068    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2071class Literal(Condition):
2072    arg_types = {"this": True, "is_string": True}
2073
2074    @property
2075    def hashable_args(self) -> t.Any:
2076        return (self.this, self.args.get("is_string"))
2077
2078    @classmethod
2079    def number(cls, number) -> Literal:
2080        return cls(this=str(number), is_string=False)
2081
2082    @classmethod
2083    def string(cls, string) -> Literal:
2084        return cls(this=str(string), is_string=True)
2085
2086    @property
2087    def output_name(self) -> str:
2088        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2074    @property
2075    def hashable_args(self) -> t.Any:
2076        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2078    @classmethod
2079    def number(cls, number) -> Literal:
2080        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2082    @classmethod
2083    def string(cls, string) -> Literal:
2084        return cls(this=str(string), is_string=True)
output_name: str
2086    @property
2087    def output_name(self) -> str:
2088        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'literal'
class Join(Expression):
2091class Join(Expression):
2092    arg_types = {
2093        "this": True,
2094        "on": False,
2095        "side": False,
2096        "kind": False,
2097        "using": False,
2098        "method": False,
2099        "global": False,
2100        "hint": False,
2101    }
2102
2103    @property
2104    def method(self) -> str:
2105        return self.text("method").upper()
2106
2107    @property
2108    def kind(self) -> str:
2109        return self.text("kind").upper()
2110
2111    @property
2112    def side(self) -> str:
2113        return self.text("side").upper()
2114
2115    @property
2116    def hint(self) -> str:
2117        return self.text("hint").upper()
2118
2119    @property
2120    def alias_or_name(self) -> str:
2121        return self.this.alias_or_name
2122
2123    def on(
2124        self,
2125        *expressions: t.Optional[ExpOrStr],
2126        append: bool = True,
2127        dialect: DialectType = None,
2128        copy: bool = True,
2129        **opts,
2130    ) -> Join:
2131        """
2132        Append to or set the ON expressions.
2133
2134        Example:
2135            >>> import sqlglot
2136            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2137            'JOIN x ON y = 1'
2138
2139        Args:
2140            *expressions: the SQL code strings to parse.
2141                If an `Expression` instance is passed, it will be used as-is.
2142                Multiple expressions are combined with an AND operator.
2143            append: if `True`, AND the new expressions to any existing expression.
2144                Otherwise, this resets the expression.
2145            dialect: the dialect used to parse the input expressions.
2146            copy: if `False`, modify this expression instance in-place.
2147            opts: other options to use to parse the input expressions.
2148
2149        Returns:
2150            The modified Join expression.
2151        """
2152        join = _apply_conjunction_builder(
2153            *expressions,
2154            instance=self,
2155            arg="on",
2156            append=append,
2157            dialect=dialect,
2158            copy=copy,
2159            **opts,
2160        )
2161
2162        if join.kind == "CROSS":
2163            join.set("kind", None)
2164
2165        return join
2166
2167    def using(
2168        self,
2169        *expressions: t.Optional[ExpOrStr],
2170        append: bool = True,
2171        dialect: DialectType = None,
2172        copy: bool = True,
2173        **opts,
2174    ) -> Join:
2175        """
2176        Append to or set the USING expressions.
2177
2178        Example:
2179            >>> import sqlglot
2180            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2181            'JOIN x USING (foo, bla)'
2182
2183        Args:
2184            *expressions: the SQL code strings to parse.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            append: if `True`, concatenate the new expressions to the existing "using" list.
2187                Otherwise, this resets the expression.
2188            dialect: the dialect used to parse the input expressions.
2189            copy: if `False`, modify this expression instance in-place.
2190            opts: other options to use to parse the input expressions.
2191
2192        Returns:
2193            The modified Join expression.
2194        """
2195        join = _apply_list_builder(
2196            *expressions,
2197            instance=self,
2198            arg="using",
2199            append=append,
2200            dialect=dialect,
2201            copy=copy,
2202            **opts,
2203        )
2204
2205        if join.kind == "CROSS":
2206            join.set("kind", None)
2207
2208        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
2103    @property
2104    def method(self) -> str:
2105        return self.text("method").upper()
kind: str
2107    @property
2108    def kind(self) -> str:
2109        return self.text("kind").upper()
side: str
2111    @property
2112    def side(self) -> str:
2113        return self.text("side").upper()
hint: str
2115    @property
2116    def hint(self) -> str:
2117        return self.text("hint").upper()
alias_or_name: str
2119    @property
2120    def alias_or_name(self) -> str:
2121        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2123    def on(
2124        self,
2125        *expressions: t.Optional[ExpOrStr],
2126        append: bool = True,
2127        dialect: DialectType = None,
2128        copy: bool = True,
2129        **opts,
2130    ) -> Join:
2131        """
2132        Append to or set the ON expressions.
2133
2134        Example:
2135            >>> import sqlglot
2136            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2137            'JOIN x ON y = 1'
2138
2139        Args:
2140            *expressions: the SQL code strings to parse.
2141                If an `Expression` instance is passed, it will be used as-is.
2142                Multiple expressions are combined with an AND operator.
2143            append: if `True`, AND the new expressions to any existing expression.
2144                Otherwise, this resets the expression.
2145            dialect: the dialect used to parse the input expressions.
2146            copy: if `False`, modify this expression instance in-place.
2147            opts: other options to use to parse the input expressions.
2148
2149        Returns:
2150            The modified Join expression.
2151        """
2152        join = _apply_conjunction_builder(
2153            *expressions,
2154            instance=self,
2155            arg="on",
2156            append=append,
2157            dialect=dialect,
2158            copy=copy,
2159            **opts,
2160        )
2161
2162        if join.kind == "CROSS":
2163            join.set("kind", None)
2164
2165        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2167    def using(
2168        self,
2169        *expressions: t.Optional[ExpOrStr],
2170        append: bool = True,
2171        dialect: DialectType = None,
2172        copy: bool = True,
2173        **opts,
2174    ) -> Join:
2175        """
2176        Append to or set the USING expressions.
2177
2178        Example:
2179            >>> import sqlglot
2180            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2181            'JOIN x USING (foo, bla)'
2182
2183        Args:
2184            *expressions: the SQL code strings to parse.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            append: if `True`, concatenate the new expressions to the existing "using" list.
2187                Otherwise, this resets the expression.
2188            dialect: the dialect used to parse the input expressions.
2189            copy: if `False`, modify this expression instance in-place.
2190            opts: other options to use to parse the input expressions.
2191
2192        Returns:
2193            The modified Join expression.
2194        """
2195        join = _apply_list_builder(
2196            *expressions,
2197            instance=self,
2198            arg="using",
2199            append=append,
2200            dialect=dialect,
2201            copy=copy,
2202            **opts,
2203        )
2204
2205        if join.kind == "CROSS":
2206            join.set("kind", None)
2207
2208        return join

Append to or set the USING expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
'JOIN x USING (foo, bla)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, concatenate the new expressions to the existing "using" list. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

key = 'join'
class Lateral(UDTF):
2211class Lateral(UDTF):
2212    arg_types = {
2213        "this": True,
2214        "view": False,
2215        "outer": False,
2216        "alias": False,
2217        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2218    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2221class MatchRecognize(Expression):
2222    arg_types = {
2223        "partition_by": False,
2224        "order": False,
2225        "measures": False,
2226        "rows": False,
2227        "after": False,
2228        "pattern": False,
2229        "define": False,
2230        "alias": False,
2231    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2236class Final(Expression):
2237    pass
key = 'final'
class Offset(Expression):
2240class Offset(Expression):
2241    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2244class Order(Expression):
2245    arg_types = {
2246        "this": False,
2247        "expressions": True,
2248        "interpolate": False,
2249        "siblings": False,
2250    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2254class WithFill(Expression):
2255    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2260class Cluster(Order):
2261    pass
key = 'cluster'
class Distribute(Order):
2264class Distribute(Order):
2265    pass
key = 'distribute'
class Sort(Order):
2268class Sort(Order):
2269    pass
key = 'sort'
class Ordered(Expression):
2272class Ordered(Expression):
2273    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2276class Property(Expression):
2277    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2280class AlgorithmProperty(Property):
2281    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2284class AutoIncrementProperty(Property):
2285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2289class AutoRefreshProperty(Property):
2290    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2293class BackupProperty(Property):
2294    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2297class BlockCompressionProperty(Property):
2298    arg_types = {
2299        "autotemp": False,
2300        "always": False,
2301        "default": False,
2302        "manual": False,
2303        "never": False,
2304    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2307class CharacterSetProperty(Property):
2308    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2311class ChecksumProperty(Property):
2312    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2315class CollateProperty(Property):
2316    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2319class CopyGrantsProperty(Property):
2320    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2323class DataBlocksizeProperty(Property):
2324    arg_types = {
2325        "size": False,
2326        "units": False,
2327        "minimum": False,
2328        "maximum": False,
2329        "default": False,
2330    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2333class DefinerProperty(Property):
2334    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2337class DistKeyProperty(Property):
2338    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2341class DistStyleProperty(Property):
2342    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2345class EngineProperty(Property):
2346    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2349class HeapProperty(Property):
2350    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2353class ToTableProperty(Property):
2354    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2357class ExecuteAsProperty(Property):
2358    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2361class ExternalProperty(Property):
2362    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2365class FallbackProperty(Property):
2366    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2369class FileFormatProperty(Property):
2370    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2373class FreespaceProperty(Property):
2374    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2377class GlobalProperty(Property):
2378    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2381class IcebergProperty(Property):
2382    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2385class InheritsProperty(Property):
2386    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2389class InputModelProperty(Property):
2390    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2393class OutputModelProperty(Property):
2394    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2397class IsolatedLoadingProperty(Property):
2398    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2401class JournalProperty(Property):
2402    arg_types = {
2403        "no": False,
2404        "dual": False,
2405        "before": False,
2406        "local": False,
2407        "after": False,
2408    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2411class LanguageProperty(Property):
2412    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2416class ClusteredByProperty(Property):
2417    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2420class DictProperty(Property):
2421    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2424class DictSubProperty(Property):
2425    pass
key = 'dictsubproperty'
class DictRange(Property):
2428class DictRange(Property):
2429    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2434class OnCluster(Property):
2435    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2438class LikeProperty(Property):
2439    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2442class LocationProperty(Property):
2443    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2446class LockProperty(Property):
2447    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2450class LockingProperty(Property):
2451    arg_types = {
2452        "this": False,
2453        "kind": True,
2454        "for_or_in": False,
2455        "lock_type": True,
2456        "override": False,
2457    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2460class LogProperty(Property):
2461    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2464class MaterializedProperty(Property):
2465    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2468class MergeBlockRatioProperty(Property):
2469    arg_types = {"this": False, "no": False, "default": False, "percent": False}
arg_types = {'this': False, 'no': False, 'default': False, 'percent': False}
key = 'mergeblockratioproperty'
class NoPrimaryIndexProperty(Property):
2472class NoPrimaryIndexProperty(Property):
2473    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2476class OnProperty(Property):
2477    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2480class OnCommitProperty(Property):
2481    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2484class PartitionedByProperty(Property):
2485    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2489class PartitionBoundSpec(Expression):
2490    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2491    arg_types = {
2492        "this": False,
2493        "expression": False,
2494        "from_expressions": False,
2495        "to_expressions": False,
2496    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2499class PartitionedOfProperty(Property):
2500    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2501    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2504class RemoteWithConnectionModelProperty(Property):
2505    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2508class ReturnsProperty(Property):
2509    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2512class RowFormatProperty(Property):
2513    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2516class RowFormatDelimitedProperty(Property):
2517    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2518    arg_types = {
2519        "fields": False,
2520        "escaped": False,
2521        "collection_items": False,
2522        "map_keys": False,
2523        "lines": False,
2524        "null": False,
2525        "serde": False,
2526    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2529class RowFormatSerdeProperty(Property):
2530    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2534class QueryTransform(Expression):
2535    arg_types = {
2536        "expressions": True,
2537        "command_script": True,
2538        "schema": False,
2539        "row_format_before": False,
2540        "record_writer": False,
2541        "row_format_after": False,
2542        "record_reader": False,
2543    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
2546class SampleProperty(Property):
2547    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2550class SchemaCommentProperty(Property):
2551    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2554class SerdeProperties(Property):
2555    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2558class SetProperty(Property):
2559    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2562class SharingProperty(Property):
2563    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2566class SetConfigProperty(Property):
2567    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2570class SettingsProperty(Property):
2571    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2574class SortKeyProperty(Property):
2575    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2578class SqlReadWriteProperty(Property):
2579    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2582class SqlSecurityProperty(Property):
2583    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2586class StabilityProperty(Property):
2587    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2590class TemporaryProperty(Property):
2591    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2594class TransformModelProperty(Property):
2595    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2598class TransientProperty(Property):
2599    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2602class UnloggedProperty(Property):
2603    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2607class ViewAttributeProperty(Property):
2608    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2611class VolatileProperty(Property):
2612    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2615class WithDataProperty(Property):
2616    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2619class WithJournalTableProperty(Property):
2620    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2623class WithSystemVersioningProperty(Property):
2624    # this -> history table name, expression -> data consistency check
2625    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2628class Properties(Expression):
2629    arg_types = {"expressions": True}
2630
2631    NAME_TO_PROPERTY = {
2632        "ALGORITHM": AlgorithmProperty,
2633        "AUTO_INCREMENT": AutoIncrementProperty,
2634        "CHARACTER SET": CharacterSetProperty,
2635        "CLUSTERED_BY": ClusteredByProperty,
2636        "COLLATE": CollateProperty,
2637        "COMMENT": SchemaCommentProperty,
2638        "DEFINER": DefinerProperty,
2639        "DISTKEY": DistKeyProperty,
2640        "DISTSTYLE": DistStyleProperty,
2641        "ENGINE": EngineProperty,
2642        "EXECUTE AS": ExecuteAsProperty,
2643        "FORMAT": FileFormatProperty,
2644        "LANGUAGE": LanguageProperty,
2645        "LOCATION": LocationProperty,
2646        "LOCK": LockProperty,
2647        "PARTITIONED_BY": PartitionedByProperty,
2648        "RETURNS": ReturnsProperty,
2649        "ROW_FORMAT": RowFormatProperty,
2650        "SORTKEY": SortKeyProperty,
2651    }
2652
2653    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2654
2655    # CREATE property locations
2656    # Form: schema specified
2657    #   create [POST_CREATE]
2658    #     table a [POST_NAME]
2659    #     (b int) [POST_SCHEMA]
2660    #     with ([POST_WITH])
2661    #     index (b) [POST_INDEX]
2662    #
2663    # Form: alias selection
2664    #   create [POST_CREATE]
2665    #     table a [POST_NAME]
2666    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2667    #     index (c) [POST_INDEX]
2668    class Location(AutoName):
2669        POST_CREATE = auto()
2670        POST_NAME = auto()
2671        POST_SCHEMA = auto()
2672        POST_WITH = auto()
2673        POST_ALIAS = auto()
2674        POST_EXPRESSION = auto()
2675        POST_INDEX = auto()
2676        UNSUPPORTED = auto()
2677
2678    @classmethod
2679    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2680        expressions = []
2681        for key, value in properties_dict.items():
2682            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2683            if property_cls:
2684                expressions.append(property_cls(this=convert(value)))
2685            else:
2686                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2687
2688        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2678    @classmethod
2679    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2680        expressions = []
2681        for key, value in properties_dict.items():
2682            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2683            if property_cls:
2684                expressions.append(property_cls(this=convert(value)))
2685            else:
2686                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2687
2688        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2668    class Location(AutoName):
2669        POST_CREATE = auto()
2670        POST_NAME = auto()
2671        POST_SCHEMA = auto()
2672        POST_WITH = auto()
2673        POST_ALIAS = auto()
2674        POST_EXPRESSION = auto()
2675        POST_INDEX = auto()
2676        UNSUPPORTED = auto()

An enumeration.

POST_CREATE = <Location.POST_CREATE: 'POST_CREATE'>
POST_NAME = <Location.POST_NAME: 'POST_NAME'>
POST_SCHEMA = <Location.POST_SCHEMA: 'POST_SCHEMA'>
POST_WITH = <Location.POST_WITH: 'POST_WITH'>
POST_ALIAS = <Location.POST_ALIAS: 'POST_ALIAS'>
POST_EXPRESSION = <Location.POST_EXPRESSION: 'POST_EXPRESSION'>
POST_INDEX = <Location.POST_INDEX: 'POST_INDEX'>
UNSUPPORTED = <Location.UNSUPPORTED: 'UNSUPPORTED'>
Inherited Members
enum.Enum
name
value
class Qualify(Expression):
2691class Qualify(Expression):
2692    pass
key = 'qualify'
class InputOutputFormat(Expression):
2695class InputOutputFormat(Expression):
2696    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2700class Return(Expression):
2701    pass
key = 'return'
class Reference(Expression):
2704class Reference(Expression):
2705    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2708class Tuple(Expression):
2709    arg_types = {"expressions": False}
2710
2711    def isin(
2712        self,
2713        *expressions: t.Any,
2714        query: t.Optional[ExpOrStr] = None,
2715        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2716        copy: bool = True,
2717        **opts,
2718    ) -> In:
2719        return In(
2720            this=maybe_copy(self, copy),
2721            expressions=[convert(e, copy=copy) for e in expressions],
2722            query=maybe_parse(query, copy=copy, **opts) if query else None,
2723            unnest=(
2724                Unnest(
2725                    expressions=[
2726                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2727                        for e in ensure_list(unnest)
2728                    ]
2729                )
2730                if unnest
2731                else None
2732            ),
2733        )
arg_types = {'expressions': False}
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
2711    def isin(
2712        self,
2713        *expressions: t.Any,
2714        query: t.Optional[ExpOrStr] = None,
2715        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2716        copy: bool = True,
2717        **opts,
2718    ) -> In:
2719        return In(
2720            this=maybe_copy(self, copy),
2721            expressions=[convert(e, copy=copy) for e in expressions],
2722            query=maybe_parse(query, copy=copy, **opts) if query else None,
2723            unnest=(
2724                Unnest(
2725                    expressions=[
2726                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2727                        for e in ensure_list(unnest)
2728                    ]
2729                )
2730                if unnest
2731                else None
2732            ),
2733        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
class QueryOption(Expression):
2764class QueryOption(Expression):
2765    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2769class WithTableHint(Expression):
2770    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2774class IndexTableHint(Expression):
2775    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2779class HistoricalData(Expression):
2780    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2783class Table(Expression):
2784    arg_types = {
2785        "this": False,
2786        "alias": False,
2787        "db": False,
2788        "catalog": False,
2789        "laterals": False,
2790        "joins": False,
2791        "pivots": False,
2792        "hints": False,
2793        "system_time": False,
2794        "version": False,
2795        "format": False,
2796        "pattern": False,
2797        "ordinality": False,
2798        "when": False,
2799        "only": False,
2800    }
2801
2802    @property
2803    def name(self) -> str:
2804        if isinstance(self.this, Func):
2805            return ""
2806        return self.this.name
2807
2808    @property
2809    def db(self) -> str:
2810        return self.text("db")
2811
2812    @property
2813    def catalog(self) -> str:
2814        return self.text("catalog")
2815
2816    @property
2817    def selects(self) -> t.List[Expression]:
2818        return []
2819
2820    @property
2821    def named_selects(self) -> t.List[str]:
2822        return []
2823
2824    @property
2825    def parts(self) -> t.List[Expression]:
2826        """Return the parts of a table in order catalog, db, table."""
2827        parts: t.List[Expression] = []
2828
2829        for arg in ("catalog", "db", "this"):
2830            part = self.args.get(arg)
2831
2832            if isinstance(part, Dot):
2833                parts.extend(part.flatten())
2834            elif isinstance(part, Expression):
2835                parts.append(part)
2836
2837        return parts
2838
2839    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2840        parts = self.parts
2841        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2842        alias = self.args.get("alias")
2843        if alias:
2844            col = alias_(col, alias.this, copy=copy)
2845        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False}
name: str
2802    @property
2803    def name(self) -> str:
2804        if isinstance(self.this, Func):
2805            return ""
2806        return self.this.name
db: str
2808    @property
2809    def db(self) -> str:
2810        return self.text("db")
catalog: str
2812    @property
2813    def catalog(self) -> str:
2814        return self.text("catalog")
selects: List[Expression]
2816    @property
2817    def selects(self) -> t.List[Expression]:
2818        return []
named_selects: List[str]
2820    @property
2821    def named_selects(self) -> t.List[str]:
2822        return []
parts: List[Expression]
2824    @property
2825    def parts(self) -> t.List[Expression]:
2826        """Return the parts of a table in order catalog, db, table."""
2827        parts: t.List[Expression] = []
2828
2829        for arg in ("catalog", "db", "this"):
2830            part = self.args.get(arg)
2831
2832            if isinstance(part, Dot):
2833                parts.extend(part.flatten())
2834            elif isinstance(part, Expression):
2835                parts.append(part)
2836
2837        return parts

Return the parts of a table in order catalog, db, table.

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2839    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2840        parts = self.parts
2841        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2842        alias = self.args.get("alias")
2843        if alias:
2844            col = alias_(col, alias.this, copy=copy)
2845        return col
key = 'table'
class Union(Query):
2848class Union(Query):
2849    arg_types = {
2850        "with": False,
2851        "this": True,
2852        "expression": True,
2853        "distinct": False,
2854        "by_name": False,
2855        **QUERY_MODIFIERS,
2856    }
2857
2858    def select(
2859        self,
2860        *expressions: t.Optional[ExpOrStr],
2861        append: bool = True,
2862        dialect: DialectType = None,
2863        copy: bool = True,
2864        **opts,
2865    ) -> Union:
2866        this = maybe_copy(self, copy)
2867        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2868        this.expression.unnest().select(
2869            *expressions, append=append, dialect=dialect, copy=False, **opts
2870        )
2871        return this
2872
2873    @property
2874    def named_selects(self) -> t.List[str]:
2875        return self.this.unnest().named_selects
2876
2877    @property
2878    def is_star(self) -> bool:
2879        return self.this.is_star or self.expression.is_star
2880
2881    @property
2882    def selects(self) -> t.List[Expression]:
2883        return self.this.unnest().selects
2884
2885    @property
2886    def left(self) -> Expression:
2887        return self.this
2888
2889    @property
2890    def right(self) -> Expression:
2891        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
2858    def select(
2859        self,
2860        *expressions: t.Optional[ExpOrStr],
2861        append: bool = True,
2862        dialect: DialectType = None,
2863        copy: bool = True,
2864        **opts,
2865    ) -> Union:
2866        this = maybe_copy(self, copy)
2867        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2868        this.expression.unnest().select(
2869            *expressions, append=append, dialect=dialect, copy=False, **opts
2870        )
2871        return this

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

named_selects: List[str]
2873    @property
2874    def named_selects(self) -> t.List[str]:
2875        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2877    @property
2878    def is_star(self) -> bool:
2879        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2881    @property
2882    def selects(self) -> t.List[Expression]:
2883        return self.this.unnest().selects

Returns the query's projections.

left: Expression
2885    @property
2886    def left(self) -> Expression:
2887        return self.this
right: Expression
2889    @property
2890    def right(self) -> Expression:
2891        return self.expression
key = 'union'
class Except(Union):
2894class Except(Union):
2895    pass
key = 'except'
class Intersect(Union):
2898class Intersect(Union):
2899    pass
key = 'intersect'
class Unnest(UDTF):
2902class Unnest(UDTF):
2903    arg_types = {
2904        "expressions": True,
2905        "alias": False,
2906        "offset": False,
2907    }
2908
2909    @property
2910    def selects(self) -> t.List[Expression]:
2911        columns = super().selects
2912        offset = self.args.get("offset")
2913        if offset:
2914            columns = columns + [to_identifier("offset") if offset is True else offset]
2915        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
2909    @property
2910    def selects(self) -> t.List[Expression]:
2911        columns = super().selects
2912        offset = self.args.get("offset")
2913        if offset:
2914            columns = columns + [to_identifier("offset") if offset is True else offset]
2915        return columns
key = 'unnest'
class Update(Expression):
2918class Update(Expression):
2919    arg_types = {
2920        "with": False,
2921        "this": False,
2922        "expressions": True,
2923        "from": False,
2924        "where": False,
2925        "returning": False,
2926        "order": False,
2927        "limit": False,
2928    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2931class Values(UDTF):
2932    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
2935class Var(Expression):
2936    pass
key = 'var'
class Version(Expression):
2939class Version(Expression):
2940    """
2941    Time travel, iceberg, bigquery etc
2942    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2943    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2944    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2945    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2946    this is either TIMESTAMP or VERSION
2947    kind is ("AS OF", "BETWEEN")
2948    """
2949
2950    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2953class Schema(Expression):
2954    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2959class Lock(Expression):
2960    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
2963class Select(Query):
2964    arg_types = {
2965        "with": False,
2966        "kind": False,
2967        "expressions": False,
2968        "hint": False,
2969        "distinct": False,
2970        "into": False,
2971        "from": False,
2972        **QUERY_MODIFIERS,
2973    }
2974
2975    def from_(
2976        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2977    ) -> Select:
2978        """
2979        Set the FROM expression.
2980
2981        Example:
2982            >>> Select().from_("tbl").select("x").sql()
2983            'SELECT x FROM tbl'
2984
2985        Args:
2986            expression : the SQL code strings to parse.
2987                If a `From` instance is passed, this is used as-is.
2988                If another `Expression` instance is passed, it will be wrapped in a `From`.
2989            dialect: the dialect used to parse the input expression.
2990            copy: if `False`, modify this expression instance in-place.
2991            opts: other options to use to parse the input expressions.
2992
2993        Returns:
2994            The modified Select expression.
2995        """
2996        return _apply_builder(
2997            expression=expression,
2998            instance=self,
2999            arg="from",
3000            into=From,
3001            prefix="FROM",
3002            dialect=dialect,
3003            copy=copy,
3004            **opts,
3005        )
3006
3007    def group_by(
3008        self,
3009        *expressions: t.Optional[ExpOrStr],
3010        append: bool = True,
3011        dialect: DialectType = None,
3012        copy: bool = True,
3013        **opts,
3014    ) -> Select:
3015        """
3016        Set the GROUP BY expression.
3017
3018        Example:
3019            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3020            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3021
3022        Args:
3023            *expressions: the SQL code strings to parse.
3024                If a `Group` instance is passed, this is used as-is.
3025                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3026                If nothing is passed in then a group by is not applied to the expression
3027            append: if `True`, add to any existing expressions.
3028                Otherwise, this flattens all the `Group` expression into a single expression.
3029            dialect: the dialect used to parse the input expression.
3030            copy: if `False`, modify this expression instance in-place.
3031            opts: other options to use to parse the input expressions.
3032
3033        Returns:
3034            The modified Select expression.
3035        """
3036        if not expressions:
3037            return self if not copy else self.copy()
3038
3039        return _apply_child_list_builder(
3040            *expressions,
3041            instance=self,
3042            arg="group",
3043            append=append,
3044            copy=copy,
3045            prefix="GROUP BY",
3046            into=Group,
3047            dialect=dialect,
3048            **opts,
3049        )
3050
3051    def order_by(
3052        self,
3053        *expressions: t.Optional[ExpOrStr],
3054        append: bool = True,
3055        dialect: DialectType = None,
3056        copy: bool = True,
3057        **opts,
3058    ) -> Select:
3059        """
3060        Set the ORDER BY expression.
3061
3062        Example:
3063            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
3064            'SELECT x FROM tbl ORDER BY x DESC'
3065
3066        Args:
3067            *expressions: the SQL code strings to parse.
3068                If a `Group` instance is passed, this is used as-is.
3069                If another `Expression` instance is passed, it will be wrapped in a `Order`.
3070            append: if `True`, add to any existing expressions.
3071                Otherwise, this flattens all the `Order` expression into a single expression.
3072            dialect: the dialect used to parse the input expression.
3073            copy: if `False`, modify this expression instance in-place.
3074            opts: other options to use to parse the input expressions.
3075
3076        Returns:
3077            The modified Select expression.
3078        """
3079        return _apply_child_list_builder(
3080            *expressions,
3081            instance=self,
3082            arg="order",
3083            append=append,
3084            copy=copy,
3085            prefix="ORDER BY",
3086            into=Order,
3087            dialect=dialect,
3088            **opts,
3089        )
3090
3091    def sort_by(
3092        self,
3093        *expressions: t.Optional[ExpOrStr],
3094        append: bool = True,
3095        dialect: DialectType = None,
3096        copy: bool = True,
3097        **opts,
3098    ) -> Select:
3099        """
3100        Set the SORT BY expression.
3101
3102        Example:
3103            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3104            'SELECT x FROM tbl SORT BY x DESC'
3105
3106        Args:
3107            *expressions: the SQL code strings to parse.
3108                If a `Group` instance is passed, this is used as-is.
3109                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3110            append: if `True`, add to any existing expressions.
3111                Otherwise, this flattens all the `Order` expression into a single expression.
3112            dialect: the dialect used to parse the input expression.
3113            copy: if `False`, modify this expression instance in-place.
3114            opts: other options to use to parse the input expressions.
3115
3116        Returns:
3117            The modified Select expression.
3118        """
3119        return _apply_child_list_builder(
3120            *expressions,
3121            instance=self,
3122            arg="sort",
3123            append=append,
3124            copy=copy,
3125            prefix="SORT BY",
3126            into=Sort,
3127            dialect=dialect,
3128            **opts,
3129        )
3130
3131    def cluster_by(
3132        self,
3133        *expressions: t.Optional[ExpOrStr],
3134        append: bool = True,
3135        dialect: DialectType = None,
3136        copy: bool = True,
3137        **opts,
3138    ) -> Select:
3139        """
3140        Set the CLUSTER BY expression.
3141
3142        Example:
3143            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3144            'SELECT x FROM tbl CLUSTER BY x DESC'
3145
3146        Args:
3147            *expressions: the SQL code strings to parse.
3148                If a `Group` instance is passed, this is used as-is.
3149                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3150            append: if `True`, add to any existing expressions.
3151                Otherwise, this flattens all the `Order` expression into a single expression.
3152            dialect: the dialect used to parse the input expression.
3153            copy: if `False`, modify this expression instance in-place.
3154            opts: other options to use to parse the input expressions.
3155
3156        Returns:
3157            The modified Select expression.
3158        """
3159        return _apply_child_list_builder(
3160            *expressions,
3161            instance=self,
3162            arg="cluster",
3163            append=append,
3164            copy=copy,
3165            prefix="CLUSTER BY",
3166            into=Cluster,
3167            dialect=dialect,
3168            **opts,
3169        )
3170
3171    def limit(
3172        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3173    ) -> Select:
3174        return _apply_builder(
3175            expression=expression,
3176            instance=self,
3177            arg="limit",
3178            into=Limit,
3179            prefix="LIMIT",
3180            dialect=dialect,
3181            copy=copy,
3182            into_arg="expression",
3183            **opts,
3184        )
3185
3186    def offset(
3187        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3188    ) -> Select:
3189        """
3190        Set the OFFSET expression.
3191
3192        Example:
3193            >>> Select().from_("tbl").select("x").offset(10).sql()
3194            'SELECT x FROM tbl OFFSET 10'
3195
3196        Args:
3197            expression: the SQL code string to parse.
3198                This can also be an integer.
3199                If a `Offset` instance is passed, this is used as-is.
3200                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3201            dialect: the dialect used to parse the input expression.
3202            copy: if `False`, modify this expression instance in-place.
3203            opts: other options to use to parse the input expressions.
3204
3205        Returns:
3206            The modified Select expression.
3207        """
3208        return _apply_builder(
3209            expression=expression,
3210            instance=self,
3211            arg="offset",
3212            into=Offset,
3213            prefix="OFFSET",
3214            dialect=dialect,
3215            copy=copy,
3216            into_arg="expression",
3217            **opts,
3218        )
3219
3220    def select(
3221        self,
3222        *expressions: t.Optional[ExpOrStr],
3223        append: bool = True,
3224        dialect: DialectType = None,
3225        copy: bool = True,
3226        **opts,
3227    ) -> Select:
3228        return _apply_list_builder(
3229            *expressions,
3230            instance=self,
3231            arg="expressions",
3232            append=append,
3233            dialect=dialect,
3234            into=Expression,
3235            copy=copy,
3236            **opts,
3237        )
3238
3239    def lateral(
3240        self,
3241        *expressions: t.Optional[ExpOrStr],
3242        append: bool = True,
3243        dialect: DialectType = None,
3244        copy: bool = True,
3245        **opts,
3246    ) -> Select:
3247        """
3248        Append to or set the LATERAL expressions.
3249
3250        Example:
3251            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3252            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3253
3254        Args:
3255            *expressions: the SQL code strings to parse.
3256                If an `Expression` instance is passed, it will be used as-is.
3257            append: if `True`, add to any existing expressions.
3258                Otherwise, this resets the expressions.
3259            dialect: the dialect used to parse the input expressions.
3260            copy: if `False`, modify this expression instance in-place.
3261            opts: other options to use to parse the input expressions.
3262
3263        Returns:
3264            The modified Select expression.
3265        """
3266        return _apply_list_builder(
3267            *expressions,
3268            instance=self,
3269            arg="laterals",
3270            append=append,
3271            into=Lateral,
3272            prefix="LATERAL VIEW",
3273            dialect=dialect,
3274            copy=copy,
3275            **opts,
3276        )
3277
3278    def join(
3279        self,
3280        expression: ExpOrStr,
3281        on: t.Optional[ExpOrStr] = None,
3282        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3283        append: bool = True,
3284        join_type: t.Optional[str] = None,
3285        join_alias: t.Optional[Identifier | str] = None,
3286        dialect: DialectType = None,
3287        copy: bool = True,
3288        **opts,
3289    ) -> Select:
3290        """
3291        Append to or set the JOIN expressions.
3292
3293        Example:
3294            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3295            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3296
3297            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3298            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3299
3300            Use `join_type` to change the type of join:
3301
3302            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3303            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3304
3305        Args:
3306            expression: the SQL code string to parse.
3307                If an `Expression` instance is passed, it will be used as-is.
3308            on: optionally specify the join "on" criteria as a SQL string.
3309                If an `Expression` instance is passed, it will be used as-is.
3310            using: optionally specify the join "using" criteria as a SQL string.
3311                If an `Expression` instance is passed, it will be used as-is.
3312            append: if `True`, add to any existing expressions.
3313                Otherwise, this resets the expressions.
3314            join_type: if set, alter the parsed join type.
3315            join_alias: an optional alias for the joined source.
3316            dialect: the dialect used to parse the input expressions.
3317            copy: if `False`, modify this expression instance in-place.
3318            opts: other options to use to parse the input expressions.
3319
3320        Returns:
3321            Select: the modified expression.
3322        """
3323        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3324
3325        try:
3326            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3327        except ParseError:
3328            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3329
3330        join = expression if isinstance(expression, Join) else Join(this=expression)
3331
3332        if isinstance(join.this, Select):
3333            join.this.replace(join.this.subquery())
3334
3335        if join_type:
3336            method: t.Optional[Token]
3337            side: t.Optional[Token]
3338            kind: t.Optional[Token]
3339
3340            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3341
3342            if method:
3343                join.set("method", method.text)
3344            if side:
3345                join.set("side", side.text)
3346            if kind:
3347                join.set("kind", kind.text)
3348
3349        if on:
3350            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3351            join.set("on", on)
3352
3353        if using:
3354            join = _apply_list_builder(
3355                *ensure_list(using),
3356                instance=join,
3357                arg="using",
3358                append=append,
3359                copy=copy,
3360                into=Identifier,
3361                **opts,
3362            )
3363
3364        if join_alias:
3365            join.set("this", alias_(join.this, join_alias, table=True))
3366
3367        return _apply_list_builder(
3368            join,
3369            instance=self,
3370            arg="joins",
3371            append=append,
3372            copy=copy,
3373            **opts,
3374        )
3375
3376    def where(
3377        self,
3378        *expressions: t.Optional[ExpOrStr],
3379        append: bool = True,
3380        dialect: DialectType = None,
3381        copy: bool = True,
3382        **opts,
3383    ) -> Select:
3384        """
3385        Append to or set the WHERE expressions.
3386
3387        Example:
3388            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3389            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3390
3391        Args:
3392            *expressions: the SQL code strings to parse.
3393                If an `Expression` instance is passed, it will be used as-is.
3394                Multiple expressions are combined with an AND operator.
3395            append: if `True`, AND the new expressions to any existing expression.
3396                Otherwise, this resets the expression.
3397            dialect: the dialect used to parse the input expressions.
3398            copy: if `False`, modify this expression instance in-place.
3399            opts: other options to use to parse the input expressions.
3400
3401        Returns:
3402            Select: the modified expression.
3403        """
3404        return _apply_conjunction_builder(
3405            *expressions,
3406            instance=self,
3407            arg="where",
3408            append=append,
3409            into=Where,
3410            dialect=dialect,
3411            copy=copy,
3412            **opts,
3413        )
3414
3415    def having(
3416        self,
3417        *expressions: t.Optional[ExpOrStr],
3418        append: bool = True,
3419        dialect: DialectType = None,
3420        copy: bool = True,
3421        **opts,
3422    ) -> Select:
3423        """
3424        Append to or set the HAVING expressions.
3425
3426        Example:
3427            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3428            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3429
3430        Args:
3431            *expressions: the SQL code strings to parse.
3432                If an `Expression` instance is passed, it will be used as-is.
3433                Multiple expressions are combined with an AND operator.
3434            append: if `True`, AND the new expressions to any existing expression.
3435                Otherwise, this resets the expression.
3436            dialect: the dialect used to parse the input expressions.
3437            copy: if `False`, modify this expression instance in-place.
3438            opts: other options to use to parse the input expressions.
3439
3440        Returns:
3441            The modified Select expression.
3442        """
3443        return _apply_conjunction_builder(
3444            *expressions,
3445            instance=self,
3446            arg="having",
3447            append=append,
3448            into=Having,
3449            dialect=dialect,
3450            copy=copy,
3451            **opts,
3452        )
3453
3454    def window(
3455        self,
3456        *expressions: t.Optional[ExpOrStr],
3457        append: bool = True,
3458        dialect: DialectType = None,
3459        copy: bool = True,
3460        **opts,
3461    ) -> Select:
3462        return _apply_list_builder(
3463            *expressions,
3464            instance=self,
3465            arg="windows",
3466            append=append,
3467            into=Window,
3468            dialect=dialect,
3469            copy=copy,
3470            **opts,
3471        )
3472
3473    def qualify(
3474        self,
3475        *expressions: t.Optional[ExpOrStr],
3476        append: bool = True,
3477        dialect: DialectType = None,
3478        copy: bool = True,
3479        **opts,
3480    ) -> Select:
3481        return _apply_conjunction_builder(
3482            *expressions,
3483            instance=self,
3484            arg="qualify",
3485            append=append,
3486            into=Qualify,
3487            dialect=dialect,
3488            copy=copy,
3489            **opts,
3490        )
3491
3492    def distinct(
3493        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3494    ) -> Select:
3495        """
3496        Set the OFFSET expression.
3497
3498        Example:
3499            >>> Select().from_("tbl").select("x").distinct().sql()
3500            'SELECT DISTINCT x FROM tbl'
3501
3502        Args:
3503            ons: the expressions to distinct on
3504            distinct: whether the Select should be distinct
3505            copy: if `False`, modify this expression instance in-place.
3506
3507        Returns:
3508            Select: the modified expression.
3509        """
3510        instance = maybe_copy(self, copy)
3511        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3512        instance.set("distinct", Distinct(on=on) if distinct else None)
3513        return instance
3514
3515    def ctas(
3516        self,
3517        table: ExpOrStr,
3518        properties: t.Optional[t.Dict] = None,
3519        dialect: DialectType = None,
3520        copy: bool = True,
3521        **opts,
3522    ) -> Create:
3523        """
3524        Convert this expression to a CREATE TABLE AS statement.
3525
3526        Example:
3527            >>> Select().select("*").from_("tbl").ctas("x").sql()
3528            'CREATE TABLE x AS SELECT * FROM tbl'
3529
3530        Args:
3531            table: the SQL code string to parse as the table name.
3532                If another `Expression` instance is passed, it will be used as-is.
3533            properties: an optional mapping of table properties
3534            dialect: the dialect used to parse the input table.
3535            copy: if `False`, modify this expression instance in-place.
3536            opts: other options to use to parse the input table.
3537
3538        Returns:
3539            The new Create expression.
3540        """
3541        instance = maybe_copy(self, copy)
3542        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3543
3544        properties_expression = None
3545        if properties:
3546            properties_expression = Properties.from_dict(properties)
3547
3548        return Create(
3549            this=table_expression,
3550            kind="TABLE",
3551            expression=instance,
3552            properties=properties_expression,
3553        )
3554
3555    def lock(self, update: bool = True, copy: bool = True) -> Select:
3556        """
3557        Set the locking read mode for this expression.
3558
3559        Examples:
3560            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3561            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3562
3563            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3564            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3565
3566        Args:
3567            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3568            copy: if `False`, modify this expression instance in-place.
3569
3570        Returns:
3571            The modified expression.
3572        """
3573        inst = maybe_copy(self, copy)
3574        inst.set("locks", [Lock(update=update)])
3575
3576        return inst
3577
3578    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3579        """
3580        Set hints for this expression.
3581
3582        Examples:
3583            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3584            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3585
3586        Args:
3587            hints: The SQL code strings to parse as the hints.
3588                If an `Expression` instance is passed, it will be used as-is.
3589            dialect: The dialect used to parse the hints.
3590            copy: If `False`, modify this expression instance in-place.
3591
3592        Returns:
3593            The modified expression.
3594        """
3595        inst = maybe_copy(self, copy)
3596        inst.set(
3597            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3598        )
3599
3600        return inst
3601
3602    @property
3603    def named_selects(self) -> t.List[str]:
3604        return [e.output_name for e in self.expressions if e.alias_or_name]
3605
3606    @property
3607    def is_star(self) -> bool:
3608        return any(expression.is_star for expression in self.expressions)
3609
3610    @property
3611    def selects(self) -> t.List[Expression]:
3612        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def from_( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2975    def from_(
2976        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2977    ) -> Select:
2978        """
2979        Set the FROM expression.
2980
2981        Example:
2982            >>> Select().from_("tbl").select("x").sql()
2983            'SELECT x FROM tbl'
2984
2985        Args:
2986            expression : the SQL code strings to parse.
2987                If a `From` instance is passed, this is used as-is.
2988                If another `Expression` instance is passed, it will be wrapped in a `From`.
2989            dialect: the dialect used to parse the input expression.
2990            copy: if `False`, modify this expression instance in-place.
2991            opts: other options to use to parse the input expressions.
2992
2993        Returns:
2994            The modified Select expression.
2995        """
2996        return _apply_builder(
2997            expression=expression,
2998            instance=self,
2999            arg="from",
3000            into=From,
3001            prefix="FROM",
3002            dialect=dialect,
3003            copy=copy,
3004            **opts,
3005        )

Set the FROM expression.

Example:
>>> Select().from_("tbl").select("x").sql()
'SELECT x FROM tbl'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3007    def group_by(
3008        self,
3009        *expressions: t.Optional[ExpOrStr],
3010        append: bool = True,
3011        dialect: DialectType = None,
3012        copy: bool = True,
3013        **opts,
3014    ) -> Select:
3015        """
3016        Set the GROUP BY expression.
3017
3018        Example:
3019            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3020            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3021
3022        Args:
3023            *expressions: the SQL code strings to parse.
3024                If a `Group` instance is passed, this is used as-is.
3025                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3026                If nothing is passed in then a group by is not applied to the expression
3027            append: if `True`, add to any existing expressions.
3028                Otherwise, this flattens all the `Group` expression into a single expression.
3029            dialect: the dialect used to parse the input expression.
3030            copy: if `False`, modify this expression instance in-place.
3031            opts: other options to use to parse the input expressions.
3032
3033        Returns:
3034            The modified Select expression.
3035        """
3036        if not expressions:
3037            return self if not copy else self.copy()
3038
3039        return _apply_child_list_builder(
3040            *expressions,
3041            instance=self,
3042            arg="group",
3043            append=append,
3044            copy=copy,
3045            prefix="GROUP BY",
3046            into=Group,
3047            dialect=dialect,
3048            **opts,
3049        )

Set the GROUP BY expression.

Example:
>>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
'SELECT x, COUNT(1) FROM tbl GROUP BY x'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Group. If nothing is passed in then a group by is not applied to the expression
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Group expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def order_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3051    def order_by(
3052        self,
3053        *expressions: t.Optional[ExpOrStr],
3054        append: bool = True,
3055        dialect: DialectType = None,
3056        copy: bool = True,
3057        **opts,
3058    ) -> Select:
3059        """
3060        Set the ORDER BY expression.
3061
3062        Example:
3063            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
3064            'SELECT x FROM tbl ORDER BY x DESC'
3065
3066        Args:
3067            *expressions: the SQL code strings to parse.
3068                If a `Group` instance is passed, this is used as-is.
3069                If another `Expression` instance is passed, it will be wrapped in a `Order`.
3070            append: if `True`, add to any existing expressions.
3071                Otherwise, this flattens all the `Order` expression into a single expression.
3072            dialect: the dialect used to parse the input expression.
3073            copy: if `False`, modify this expression instance in-place.
3074            opts: other options to use to parse the input expressions.
3075
3076        Returns:
3077            The modified Select expression.
3078        """
3079        return _apply_child_list_builder(
3080            *expressions,
3081            instance=self,
3082            arg="order",
3083            append=append,
3084            copy=copy,
3085            prefix="ORDER BY",
3086            into=Order,
3087            dialect=dialect,
3088            **opts,
3089        )

Set the ORDER BY expression.

Example:
>>> Select().from_("tbl").select("x").order_by("x DESC").sql()
'SELECT x FROM tbl ORDER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Order.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3091    def sort_by(
3092        self,
3093        *expressions: t.Optional[ExpOrStr],
3094        append: bool = True,
3095        dialect: DialectType = None,
3096        copy: bool = True,
3097        **opts,
3098    ) -> Select:
3099        """
3100        Set the SORT BY expression.
3101
3102        Example:
3103            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3104            'SELECT x FROM tbl SORT BY x DESC'
3105
3106        Args:
3107            *expressions: the SQL code strings to parse.
3108                If a `Group` instance is passed, this is used as-is.
3109                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3110            append: if `True`, add to any existing expressions.
3111                Otherwise, this flattens all the `Order` expression into a single expression.
3112            dialect: the dialect used to parse the input expression.
3113            copy: if `False`, modify this expression instance in-place.
3114            opts: other options to use to parse the input expressions.
3115
3116        Returns:
3117            The modified Select expression.
3118        """
3119        return _apply_child_list_builder(
3120            *expressions,
3121            instance=self,
3122            arg="sort",
3123            append=append,
3124            copy=copy,
3125            prefix="SORT BY",
3126            into=Sort,
3127            dialect=dialect,
3128            **opts,
3129        )

Set the SORT BY expression.

Example:
>>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl SORT BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a SORT.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3131    def cluster_by(
3132        self,
3133        *expressions: t.Optional[ExpOrStr],
3134        append: bool = True,
3135        dialect: DialectType = None,
3136        copy: bool = True,
3137        **opts,
3138    ) -> Select:
3139        """
3140        Set the CLUSTER BY expression.
3141
3142        Example:
3143            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3144            'SELECT x FROM tbl CLUSTER BY x DESC'
3145
3146        Args:
3147            *expressions: the SQL code strings to parse.
3148                If a `Group` instance is passed, this is used as-is.
3149                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3150            append: if `True`, add to any existing expressions.
3151                Otherwise, this flattens all the `Order` expression into a single expression.
3152            dialect: the dialect used to parse the input expression.
3153            copy: if `False`, modify this expression instance in-place.
3154            opts: other options to use to parse the input expressions.
3155
3156        Returns:
3157            The modified Select expression.
3158        """
3159        return _apply_child_list_builder(
3160            *expressions,
3161            instance=self,
3162            arg="cluster",
3163            append=append,
3164            copy=copy,
3165            prefix="CLUSTER BY",
3166            into=Cluster,
3167            dialect=dialect,
3168            **opts,
3169        )

Set the CLUSTER BY expression.

Example:
>>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl CLUSTER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Cluster.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3171    def limit(
3172        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3173    ) -> Select:
3174        return _apply_builder(
3175            expression=expression,
3176            instance=self,
3177            arg="limit",
3178            into=Limit,
3179            prefix="LIMIT",
3180            dialect=dialect,
3181            copy=copy,
3182            into_arg="expression",
3183            **opts,
3184        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

def offset( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3186    def offset(
3187        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3188    ) -> Select:
3189        """
3190        Set the OFFSET expression.
3191
3192        Example:
3193            >>> Select().from_("tbl").select("x").offset(10).sql()
3194            'SELECT x FROM tbl OFFSET 10'
3195
3196        Args:
3197            expression: the SQL code string to parse.
3198                This can also be an integer.
3199                If a `Offset` instance is passed, this is used as-is.
3200                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3201            dialect: the dialect used to parse the input expression.
3202            copy: if `False`, modify this expression instance in-place.
3203            opts: other options to use to parse the input expressions.
3204
3205        Returns:
3206            The modified Select expression.
3207        """
3208        return _apply_builder(
3209            expression=expression,
3210            instance=self,
3211            arg="offset",
3212            into=Offset,
3213            prefix="OFFSET",
3214            dialect=dialect,
3215            copy=copy,
3216            into_arg="expression",
3217            **opts,
3218        )

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").offset(10).sql()
'SELECT x FROM tbl OFFSET 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Offset instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Offset.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3220    def select(
3221        self,
3222        *expressions: t.Optional[ExpOrStr],
3223        append: bool = True,
3224        dialect: DialectType = None,
3225        copy: bool = True,
3226        **opts,
3227    ) -> Select:
3228        return _apply_list_builder(
3229            *expressions,
3230            instance=self,
3231            arg="expressions",
3232            append=append,
3233            dialect=dialect,
3234            into=Expression,
3235            copy=copy,
3236            **opts,
3237        )

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3239    def lateral(
3240        self,
3241        *expressions: t.Optional[ExpOrStr],
3242        append: bool = True,
3243        dialect: DialectType = None,
3244        copy: bool = True,
3245        **opts,
3246    ) -> Select:
3247        """
3248        Append to or set the LATERAL expressions.
3249
3250        Example:
3251            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3252            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3253
3254        Args:
3255            *expressions: the SQL code strings to parse.
3256                If an `Expression` instance is passed, it will be used as-is.
3257            append: if `True`, add to any existing expressions.
3258                Otherwise, this resets the expressions.
3259            dialect: the dialect used to parse the input expressions.
3260            copy: if `False`, modify this expression instance in-place.
3261            opts: other options to use to parse the input expressions.
3262
3263        Returns:
3264            The modified Select expression.
3265        """
3266        return _apply_list_builder(
3267            *expressions,
3268            instance=self,
3269            arg="laterals",
3270            append=append,
3271            into=Lateral,
3272            prefix="LATERAL VIEW",
3273            dialect=dialect,
3274            copy=copy,
3275            **opts,
3276        )

Append to or set the LATERAL expressions.

Example:
>>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3278    def join(
3279        self,
3280        expression: ExpOrStr,
3281        on: t.Optional[ExpOrStr] = None,
3282        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3283        append: bool = True,
3284        join_type: t.Optional[str] = None,
3285        join_alias: t.Optional[Identifier | str] = None,
3286        dialect: DialectType = None,
3287        copy: bool = True,
3288        **opts,
3289    ) -> Select:
3290        """
3291        Append to or set the JOIN expressions.
3292
3293        Example:
3294            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3295            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3296
3297            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3298            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3299
3300            Use `join_type` to change the type of join:
3301
3302            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3303            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3304
3305        Args:
3306            expression: the SQL code string to parse.
3307                If an `Expression` instance is passed, it will be used as-is.
3308            on: optionally specify the join "on" criteria as a SQL string.
3309                If an `Expression` instance is passed, it will be used as-is.
3310            using: optionally specify the join "using" criteria as a SQL string.
3311                If an `Expression` instance is passed, it will be used as-is.
3312            append: if `True`, add to any existing expressions.
3313                Otherwise, this resets the expressions.
3314            join_type: if set, alter the parsed join type.
3315            join_alias: an optional alias for the joined source.
3316            dialect: the dialect used to parse the input expressions.
3317            copy: if `False`, modify this expression instance in-place.
3318            opts: other options to use to parse the input expressions.
3319
3320        Returns:
3321            Select: the modified expression.
3322        """
3323        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3324
3325        try:
3326            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3327        except ParseError:
3328            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3329
3330        join = expression if isinstance(expression, Join) else Join(this=expression)
3331
3332        if isinstance(join.this, Select):
3333            join.this.replace(join.this.subquery())
3334
3335        if join_type:
3336            method: t.Optional[Token]
3337            side: t.Optional[Token]
3338            kind: t.Optional[Token]
3339
3340            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3341
3342            if method:
3343                join.set("method", method.text)
3344            if side:
3345                join.set("side", side.text)
3346            if kind:
3347                join.set("kind", kind.text)
3348
3349        if on:
3350            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3351            join.set("on", on)
3352
3353        if using:
3354            join = _apply_list_builder(
3355                *ensure_list(using),
3356                instance=join,
3357                arg="using",
3358                append=append,
3359                copy=copy,
3360                into=Identifier,
3361                **opts,
3362            )
3363
3364        if join_alias:
3365            join.set("this", alias_(join.this, join_alias, table=True))
3366
3367        return _apply_list_builder(
3368            join,
3369            instance=self,
3370            arg="joins",
3371            append=append,
3372            copy=copy,
3373            **opts,
3374        )

Append to or set the JOIN expressions.

Example:
>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3376    def where(
3377        self,
3378        *expressions: t.Optional[ExpOrStr],
3379        append: bool = True,
3380        dialect: DialectType = None,
3381        copy: bool = True,
3382        **opts,
3383    ) -> Select:
3384        """
3385        Append to or set the WHERE expressions.
3386
3387        Example:
3388            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3389            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3390
3391        Args:
3392            *expressions: the SQL code strings to parse.
3393                If an `Expression` instance is passed, it will be used as-is.
3394                Multiple expressions are combined with an AND operator.
3395            append: if `True`, AND the new expressions to any existing expression.
3396                Otherwise, this resets the expression.
3397            dialect: the dialect used to parse the input expressions.
3398            copy: if `False`, modify this expression instance in-place.
3399            opts: other options to use to parse the input expressions.
3400
3401        Returns:
3402            Select: the modified expression.
3403        """
3404        return _apply_conjunction_builder(
3405            *expressions,
3406            instance=self,
3407            arg="where",
3408            append=append,
3409            into=Where,
3410            dialect=dialect,
3411            copy=copy,
3412            **opts,
3413        )

Append to or set the WHERE expressions.

Example:
>>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
"SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3415    def having(
3416        self,
3417        *expressions: t.Optional[ExpOrStr],
3418        append: bool = True,
3419        dialect: DialectType = None,
3420        copy: bool = True,
3421        **opts,
3422    ) -> Select:
3423        """
3424        Append to or set the HAVING expressions.
3425
3426        Example:
3427            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3428            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3429
3430        Args:
3431            *expressions: the SQL code strings to parse.
3432                If an `Expression` instance is passed, it will be used as-is.
3433                Multiple expressions are combined with an AND operator.
3434            append: if `True`, AND the new expressions to any existing expression.
3435                Otherwise, this resets the expression.
3436            dialect: the dialect used to parse the input expressions.
3437            copy: if `False`, modify this expression instance in-place.
3438            opts: other options to use to parse the input expressions.
3439
3440        Returns:
3441            The modified Select expression.
3442        """
3443        return _apply_conjunction_builder(
3444            *expressions,
3445            instance=self,
3446            arg="having",
3447            append=append,
3448            into=Having,
3449            dialect=dialect,
3450            copy=copy,
3451            **opts,
3452        )

Append to or set the HAVING expressions.

Example:
>>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3454    def window(
3455        self,
3456        *expressions: t.Optional[ExpOrStr],
3457        append: bool = True,
3458        dialect: DialectType = None,
3459        copy: bool = True,
3460        **opts,
3461    ) -> Select:
3462        return _apply_list_builder(
3463            *expressions,
3464            instance=self,
3465            arg="windows",
3466            append=append,
3467            into=Window,
3468            dialect=dialect,
3469            copy=copy,
3470            **opts,
3471        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3473    def qualify(
3474        self,
3475        *expressions: t.Optional[ExpOrStr],
3476        append: bool = True,
3477        dialect: DialectType = None,
3478        copy: bool = True,
3479        **opts,
3480    ) -> Select:
3481        return _apply_conjunction_builder(
3482            *expressions,
3483            instance=self,
3484            arg="qualify",
3485            append=append,
3486            into=Qualify,
3487            dialect=dialect,
3488            copy=copy,
3489            **opts,
3490        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3492    def distinct(
3493        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3494    ) -> Select:
3495        """
3496        Set the OFFSET expression.
3497
3498        Example:
3499            >>> Select().from_("tbl").select("x").distinct().sql()
3500            'SELECT DISTINCT x FROM tbl'
3501
3502        Args:
3503            ons: the expressions to distinct on
3504            distinct: whether the Select should be distinct
3505            copy: if `False`, modify this expression instance in-place.
3506
3507        Returns:
3508            Select: the modified expression.
3509        """
3510        instance = maybe_copy(self, copy)
3511        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3512        instance.set("distinct", Distinct(on=on) if distinct else None)
3513        return instance

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").distinct().sql()
'SELECT DISTINCT x FROM tbl'
Arguments:
  • ons: the expressions to distinct on
  • distinct: whether the Select should be distinct
  • copy: if False, modify this expression instance in-place.
Returns:

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
3515    def ctas(
3516        self,
3517        table: ExpOrStr,
3518        properties: t.Optional[t.Dict] = None,
3519        dialect: DialectType = None,
3520        copy: bool = True,
3521        **opts,
3522    ) -> Create:
3523        """
3524        Convert this expression to a CREATE TABLE AS statement.
3525
3526        Example:
3527            >>> Select().select("*").from_("tbl").ctas("x").sql()
3528            'CREATE TABLE x AS SELECT * FROM tbl'
3529
3530        Args:
3531            table: the SQL code string to parse as the table name.
3532                If another `Expression` instance is passed, it will be used as-is.
3533            properties: an optional mapping of table properties
3534            dialect: the dialect used to parse the input table.
3535            copy: if `False`, modify this expression instance in-place.
3536            opts: other options to use to parse the input table.
3537
3538        Returns:
3539            The new Create expression.
3540        """
3541        instance = maybe_copy(self, copy)
3542        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3543
3544        properties_expression = None
3545        if properties:
3546            properties_expression = Properties.from_dict(properties)
3547
3548        return Create(
3549            this=table_expression,
3550            kind="TABLE",
3551            expression=instance,
3552            properties=properties_expression,
3553        )

Convert this expression to a CREATE TABLE AS statement.

Example:
>>> Select().select("*").from_("tbl").ctas("x").sql()
'CREATE TABLE x AS SELECT * FROM tbl'
Arguments:
  • table: the SQL code string to parse as the table name. If another Expression instance is passed, it will be used as-is.
  • properties: an optional mapping of table properties
  • dialect: the dialect used to parse the input table.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input table.
Returns:

The new Create expression.

def lock( self, update: bool = True, copy: bool = True) -> Select:
3555    def lock(self, update: bool = True, copy: bool = True) -> Select:
3556        """
3557        Set the locking read mode for this expression.
3558
3559        Examples:
3560            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3561            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3562
3563            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3564            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3565
3566        Args:
3567            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3568            copy: if `False`, modify this expression instance in-place.
3569
3570        Returns:
3571            The modified expression.
3572        """
3573        inst = maybe_copy(self, copy)
3574        inst.set("locks", [Lock(update=update)])
3575
3576        return inst

Set the locking read mode for this expression.

Examples:
>>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
>>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
Arguments:
  • update: if True, the locking type will be FOR UPDATE, else it will be FOR SHARE.
  • copy: if False, modify this expression instance in-place.
Returns:

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
3578    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3579        """
3580        Set hints for this expression.
3581
3582        Examples:
3583            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3584            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3585
3586        Args:
3587            hints: The SQL code strings to parse as the hints.
3588                If an `Expression` instance is passed, it will be used as-is.
3589            dialect: The dialect used to parse the hints.
3590            copy: If `False`, modify this expression instance in-place.
3591
3592        Returns:
3593            The modified expression.
3594        """
3595        inst = maybe_copy(self, copy)
3596        inst.set(
3597            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3598        )
3599
3600        return inst

Set hints for this expression.

Examples:
>>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
'SELECT /*+ BROADCAST(y) */ x FROM tbl'
Arguments:
  • hints: The SQL code strings to parse as the hints. If an Expression instance is passed, it will be used as-is.
  • dialect: The dialect used to parse the hints.
  • copy: If False, modify this expression instance in-place.
Returns:

The modified expression.

named_selects: List[str]
3602    @property
3603    def named_selects(self) -> t.List[str]:
3604        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
3606    @property
3607    def is_star(self) -> bool:
3608        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3610    @property
3611    def selects(self) -> t.List[Expression]:
3612        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3618class Subquery(DerivedTable, Query):
3619    arg_types = {
3620        "this": True,
3621        "alias": False,
3622        "with": False,
3623        **QUERY_MODIFIERS,
3624    }
3625
3626    def unnest(self):
3627        """Returns the first non subquery."""
3628        expression = self
3629        while isinstance(expression, Subquery):
3630            expression = expression.this
3631        return expression
3632
3633    def unwrap(self) -> Subquery:
3634        expression = self
3635        while expression.same_parent and expression.is_wrapper:
3636            expression = t.cast(Subquery, expression.parent)
3637        return expression
3638
3639    def select(
3640        self,
3641        *expressions: t.Optional[ExpOrStr],
3642        append: bool = True,
3643        dialect: DialectType = None,
3644        copy: bool = True,
3645        **opts,
3646    ) -> Subquery:
3647        this = maybe_copy(self, copy)
3648        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3649        return this
3650
3651    @property
3652    def is_wrapper(self) -> bool:
3653        """
3654        Whether this Subquery acts as a simple wrapper around another expression.
3655
3656        SELECT * FROM (((SELECT * FROM t)))
3657                      ^
3658                      This corresponds to a "wrapper" Subquery node
3659        """
3660        return all(v is None for k, v in self.args.items() if k != "this")
3661
3662    @property
3663    def is_star(self) -> bool:
3664        return self.this.is_star
3665
3666    @property
3667    def output_name(self) -> str:
3668        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def unnest(self):
3626    def unnest(self):
3627        """Returns the first non subquery."""
3628        expression = self
3629        while isinstance(expression, Subquery):
3630            expression = expression.this
3631        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3633    def unwrap(self) -> Subquery:
3634        expression = self
3635        while expression.same_parent and expression.is_wrapper:
3636            expression = t.cast(Subquery, expression.parent)
3637        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
3639    def select(
3640        self,
3641        *expressions: t.Optional[ExpOrStr],
3642        append: bool = True,
3643        dialect: DialectType = None,
3644        copy: bool = True,
3645        **opts,
3646    ) -> Subquery:
3647        this = maybe_copy(self, copy)
3648        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3649        return this

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

is_wrapper: bool
3651    @property
3652    def is_wrapper(self) -> bool:
3653        """
3654        Whether this Subquery acts as a simple wrapper around another expression.
3655
3656        SELECT * FROM (((SELECT * FROM t)))
3657                      ^
3658                      This corresponds to a "wrapper" Subquery node
3659        """
3660        return all(v is None for k, v in self.args.items() if k != "this")

Whether this Subquery acts as a simple wrapper around another expression.

SELECT * FROM (((SELECT * FROM t))) ^ This corresponds to a "wrapper" Subquery node

is_star: bool
3662    @property
3663    def is_star(self) -> bool:
3664        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3666    @property
3667    def output_name(self) -> str:
3668        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'subquery'
class TableSample(Expression):
3671class TableSample(Expression):
3672    arg_types = {
3673        "this": False,
3674        "expressions": False,
3675        "method": False,
3676        "bucket_numerator": False,
3677        "bucket_denominator": False,
3678        "bucket_field": False,
3679        "percent": False,
3680        "rows": False,
3681        "size": False,
3682        "seed": False,
3683    }
arg_types = {'this': False, 'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
3686class Tag(Expression):
3687    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3688
3689    arg_types = {
3690        "this": False,
3691        "prefix": False,
3692        "postfix": False,
3693    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3698class Pivot(Expression):
3699    arg_types = {
3700        "this": False,
3701        "alias": False,
3702        "expressions": False,
3703        "field": False,
3704        "unpivot": False,
3705        "using": False,
3706        "group": False,
3707        "columns": False,
3708        "include_nulls": False,
3709    }
3710
3711    @property
3712    def unpivot(self) -> bool:
3713        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3711    @property
3712    def unpivot(self) -> bool:
3713        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3716class Window(Condition):
3717    arg_types = {
3718        "this": True,
3719        "partition_by": False,
3720        "order": False,
3721        "spec": False,
3722        "alias": False,
3723        "over": False,
3724        "first": False,
3725    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3728class WindowSpec(Expression):
3729    arg_types = {
3730        "kind": False,
3731        "start": False,
3732        "start_side": False,
3733        "end": False,
3734        "end_side": False,
3735    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3738class PreWhere(Expression):
3739    pass
key = 'prewhere'
class Where(Expression):
3742class Where(Expression):
3743    pass
key = 'where'
class Star(Expression):
3746class Star(Expression):
3747    arg_types = {"except": False, "replace": False}
3748
3749    @property
3750    def name(self) -> str:
3751        return "*"
3752
3753    @property
3754    def output_name(self) -> str:
3755        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3749    @property
3750    def name(self) -> str:
3751        return "*"
output_name: str
3753    @property
3754    def output_name(self) -> str:
3755        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'star'
class Parameter(Condition):
3758class Parameter(Condition):
3759    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3762class SessionParameter(Condition):
3763    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3766class Placeholder(Condition):
3767    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3770class Null(Condition):
3771    arg_types: t.Dict[str, t.Any] = {}
3772
3773    @property
3774    def name(self) -> str:
3775        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3773    @property
3774    def name(self) -> str:
3775        return "NULL"
key = 'null'
class Boolean(Condition):
3778class Boolean(Condition):
3779    pass
key = 'boolean'
class DataTypeParam(Expression):
3782class DataTypeParam(Expression):
3783    arg_types = {"this": True, "expression": False}
3784
3785    @property
3786    def name(self) -> str:
3787        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3785    @property
3786    def name(self) -> str:
3787        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3790class DataType(Expression):
3791    arg_types = {
3792        "this": True,
3793        "expressions": False,
3794        "nested": False,
3795        "values": False,
3796        "prefix": False,
3797        "kind": False,
3798    }
3799
3800    class Type(AutoName):
3801        ARRAY = auto()
3802        AGGREGATEFUNCTION = auto()
3803        SIMPLEAGGREGATEFUNCTION = auto()
3804        BIGDECIMAL = auto()
3805        BIGINT = auto()
3806        BIGSERIAL = auto()
3807        BINARY = auto()
3808        BIT = auto()
3809        BOOLEAN = auto()
3810        BPCHAR = auto()
3811        CHAR = auto()
3812        DATE = auto()
3813        DATE32 = auto()
3814        DATEMULTIRANGE = auto()
3815        DATERANGE = auto()
3816        DATETIME = auto()
3817        DATETIME64 = auto()
3818        DECIMAL = auto()
3819        DOUBLE = auto()
3820        ENUM = auto()
3821        ENUM8 = auto()
3822        ENUM16 = auto()
3823        FIXEDSTRING = auto()
3824        FLOAT = auto()
3825        GEOGRAPHY = auto()
3826        GEOMETRY = auto()
3827        HLLSKETCH = auto()
3828        HSTORE = auto()
3829        IMAGE = auto()
3830        INET = auto()
3831        INT = auto()
3832        INT128 = auto()
3833        INT256 = auto()
3834        INT4MULTIRANGE = auto()
3835        INT4RANGE = auto()
3836        INT8MULTIRANGE = auto()
3837        INT8RANGE = auto()
3838        INTERVAL = auto()
3839        IPADDRESS = auto()
3840        IPPREFIX = auto()
3841        IPV4 = auto()
3842        IPV6 = auto()
3843        JSON = auto()
3844        JSONB = auto()
3845        LONGBLOB = auto()
3846        LONGTEXT = auto()
3847        LOWCARDINALITY = auto()
3848        MAP = auto()
3849        MEDIUMBLOB = auto()
3850        MEDIUMINT = auto()
3851        MEDIUMTEXT = auto()
3852        MONEY = auto()
3853        NAME = auto()
3854        NCHAR = auto()
3855        NESTED = auto()
3856        NULL = auto()
3857        NULLABLE = auto()
3858        NUMMULTIRANGE = auto()
3859        NUMRANGE = auto()
3860        NVARCHAR = auto()
3861        OBJECT = auto()
3862        ROWVERSION = auto()
3863        SERIAL = auto()
3864        SET = auto()
3865        SMALLINT = auto()
3866        SMALLMONEY = auto()
3867        SMALLSERIAL = auto()
3868        STRUCT = auto()
3869        SUPER = auto()
3870        TEXT = auto()
3871        TINYBLOB = auto()
3872        TINYTEXT = auto()
3873        TIME = auto()
3874        TIMETZ = auto()
3875        TIMESTAMP = auto()
3876        TIMESTAMPLTZ = auto()
3877        TIMESTAMPTZ = auto()
3878        TIMESTAMP_S = auto()
3879        TIMESTAMP_MS = auto()
3880        TIMESTAMP_NS = auto()
3881        TINYINT = auto()
3882        TSMULTIRANGE = auto()
3883        TSRANGE = auto()
3884        TSTZMULTIRANGE = auto()
3885        TSTZRANGE = auto()
3886        UBIGINT = auto()
3887        UINT = auto()
3888        UINT128 = auto()
3889        UINT256 = auto()
3890        UMEDIUMINT = auto()
3891        UDECIMAL = auto()
3892        UNIQUEIDENTIFIER = auto()
3893        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3894        USERDEFINED = "USER-DEFINED"
3895        USMALLINT = auto()
3896        UTINYINT = auto()
3897        UUID = auto()
3898        VARBINARY = auto()
3899        VARCHAR = auto()
3900        VARIANT = auto()
3901        XML = auto()
3902        YEAR = auto()
3903
3904    STRUCT_TYPES = {
3905        Type.NESTED,
3906        Type.OBJECT,
3907        Type.STRUCT,
3908    }
3909
3910    NESTED_TYPES = {
3911        *STRUCT_TYPES,
3912        Type.ARRAY,
3913        Type.MAP,
3914    }
3915
3916    TEXT_TYPES = {
3917        Type.CHAR,
3918        Type.NCHAR,
3919        Type.NVARCHAR,
3920        Type.TEXT,
3921        Type.VARCHAR,
3922        Type.NAME,
3923    }
3924
3925    INTEGER_TYPES = {
3926        Type.BIGINT,
3927        Type.BIT,
3928        Type.INT,
3929        Type.INT128,
3930        Type.INT256,
3931        Type.MEDIUMINT,
3932        Type.SMALLINT,
3933        Type.TINYINT,
3934        Type.UBIGINT,
3935        Type.UINT,
3936        Type.UINT128,
3937        Type.UINT256,
3938        Type.UMEDIUMINT,
3939        Type.USMALLINT,
3940        Type.UTINYINT,
3941    }
3942
3943    FLOAT_TYPES = {
3944        Type.DOUBLE,
3945        Type.FLOAT,
3946    }
3947
3948    REAL_TYPES = {
3949        *FLOAT_TYPES,
3950        Type.BIGDECIMAL,
3951        Type.DECIMAL,
3952        Type.MONEY,
3953        Type.SMALLMONEY,
3954        Type.UDECIMAL,
3955    }
3956
3957    NUMERIC_TYPES = {
3958        *INTEGER_TYPES,
3959        *REAL_TYPES,
3960    }
3961
3962    TEMPORAL_TYPES = {
3963        Type.DATE,
3964        Type.DATE32,
3965        Type.DATETIME,
3966        Type.DATETIME64,
3967        Type.TIME,
3968        Type.TIMESTAMP,
3969        Type.TIMESTAMPLTZ,
3970        Type.TIMESTAMPTZ,
3971        Type.TIMESTAMP_MS,
3972        Type.TIMESTAMP_NS,
3973        Type.TIMESTAMP_S,
3974        Type.TIMETZ,
3975    }
3976
3977    @classmethod
3978    def build(
3979        cls,
3980        dtype: DATA_TYPE,
3981        dialect: DialectType = None,
3982        udt: bool = False,
3983        copy: bool = True,
3984        **kwargs,
3985    ) -> DataType:
3986        """
3987        Constructs a DataType object.
3988
3989        Args:
3990            dtype: the data type of interest.
3991            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3992            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3993                DataType, thus creating a user-defined type.
3994            copy: whether to copy the data type.
3995            kwargs: additional arguments to pass in the constructor of DataType.
3996
3997        Returns:
3998            The constructed DataType object.
3999        """
4000        from sqlglot import parse_one
4001
4002        if isinstance(dtype, str):
4003            if dtype.upper() == "UNKNOWN":
4004                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4005
4006            try:
4007                data_type_exp = parse_one(
4008                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4009                )
4010            except ParseError:
4011                if udt:
4012                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4013                raise
4014        elif isinstance(dtype, DataType.Type):
4015            data_type_exp = DataType(this=dtype)
4016        elif isinstance(dtype, DataType):
4017            return maybe_copy(dtype, copy)
4018        else:
4019            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4020
4021        return DataType(**{**data_type_exp.args, **kwargs})
4022
4023    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4024        """
4025        Checks whether this DataType matches one of the provided data types. Nested types or precision
4026        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4027
4028        Args:
4029            dtypes: the data types to compare this DataType to.
4030
4031        Returns:
4032            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4033        """
4034        for dtype in dtypes:
4035            other = DataType.build(dtype, copy=False, udt=True)
4036
4037            if (
4038                other.expressions
4039                or self.this == DataType.Type.USERDEFINED
4040                or other.this == DataType.Type.USERDEFINED
4041            ):
4042                matches = self == other
4043            else:
4044                matches = self.this == other.this
4045
4046            if matches:
4047                return True
4048        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NAME: 'NAME'>}
INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.INT256: 'INT256'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT256: 'UINT256'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.UINT128: 'UINT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.SMALLMONEY: 'SMALLMONEY'>}
NUMERIC_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT256: 'INT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT256: 'UINT256'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.INT: 'INT'>, <Type.MONEY: 'MONEY'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DOUBLE: 'DOUBLE'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME: 'DATETIME'>, <Type.TIME: 'TIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
3977    @classmethod
3978    def build(
3979        cls,
3980        dtype: DATA_TYPE,
3981        dialect: DialectType = None,
3982        udt: bool = False,
3983        copy: bool = True,
3984        **kwargs,
3985    ) -> DataType:
3986        """
3987        Constructs a DataType object.
3988
3989        Args:
3990            dtype: the data type of interest.
3991            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3992            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3993                DataType, thus creating a user-defined type.
3994            copy: whether to copy the data type.
3995            kwargs: additional arguments to pass in the constructor of DataType.
3996
3997        Returns:
3998            The constructed DataType object.
3999        """
4000        from sqlglot import parse_one
4001
4002        if isinstance(dtype, str):
4003            if dtype.upper() == "UNKNOWN":
4004                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4005
4006            try:
4007                data_type_exp = parse_one(
4008                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4009                )
4010            except ParseError:
4011                if udt:
4012                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4013                raise
4014        elif isinstance(dtype, DataType.Type):
4015            data_type_exp = DataType(this=dtype)
4016        elif isinstance(dtype, DataType):
4017            return maybe_copy(dtype, copy)
4018        else:
4019            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4020
4021        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4023    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4024        """
4025        Checks whether this DataType matches one of the provided data types. Nested types or precision
4026        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4027
4028        Args:
4029            dtypes: the data types to compare this DataType to.
4030
4031        Returns:
4032            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4033        """
4034        for dtype in dtypes:
4035            other = DataType.build(dtype, copy=False, udt=True)
4036
4037            if (
4038                other.expressions
4039                or self.this == DataType.Type.USERDEFINED
4040                or other.this == DataType.Type.USERDEFINED
4041            ):
4042                matches = self == other
4043            else:
4044                matches = self.this == other.this
4045
4046            if matches:
4047                return True
4048        return False

Checks whether this DataType matches one of the provided data types. Nested types or precision will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this DataType.

key = 'datatype'
class DataType.Type(sqlglot.helper.AutoName):
3800    class Type(AutoName):
3801        ARRAY = auto()
3802        AGGREGATEFUNCTION = auto()
3803        SIMPLEAGGREGATEFUNCTION = auto()
3804        BIGDECIMAL = auto()
3805        BIGINT = auto()
3806        BIGSERIAL = auto()
3807        BINARY = auto()
3808        BIT = auto()
3809        BOOLEAN = auto()
3810        BPCHAR = auto()
3811        CHAR = auto()
3812        DATE = auto()
3813        DATE32 = auto()
3814        DATEMULTIRANGE = auto()
3815        DATERANGE = auto()
3816        DATETIME = auto()
3817        DATETIME64 = auto()
3818        DECIMAL = auto()
3819        DOUBLE = auto()
3820        ENUM = auto()
3821        ENUM8 = auto()
3822        ENUM16 = auto()
3823        FIXEDSTRING = auto()
3824        FLOAT = auto()
3825        GEOGRAPHY = auto()
3826        GEOMETRY = auto()
3827        HLLSKETCH = auto()
3828        HSTORE = auto()
3829        IMAGE = auto()
3830        INET = auto()
3831        INT = auto()
3832        INT128 = auto()
3833        INT256 = auto()
3834        INT4MULTIRANGE = auto()
3835        INT4RANGE = auto()
3836        INT8MULTIRANGE = auto()
3837        INT8RANGE = auto()
3838        INTERVAL = auto()
3839        IPADDRESS = auto()
3840        IPPREFIX = auto()
3841        IPV4 = auto()
3842        IPV6 = auto()
3843        JSON = auto()
3844        JSONB = auto()
3845        LONGBLOB = auto()
3846        LONGTEXT = auto()
3847        LOWCARDINALITY = auto()
3848        MAP = auto()
3849        MEDIUMBLOB = auto()
3850        MEDIUMINT = auto()
3851        MEDIUMTEXT = auto()
3852        MONEY = auto()
3853        NAME = auto()
3854        NCHAR = auto()
3855        NESTED = auto()
3856        NULL = auto()
3857        NULLABLE = auto()
3858        NUMMULTIRANGE = auto()
3859        NUMRANGE = auto()
3860        NVARCHAR = auto()
3861        OBJECT = auto()
3862        ROWVERSION = auto()
3863        SERIAL = auto()
3864        SET = auto()
3865        SMALLINT = auto()
3866        SMALLMONEY = auto()
3867        SMALLSERIAL = auto()
3868        STRUCT = auto()
3869        SUPER = auto()
3870        TEXT = auto()
3871        TINYBLOB = auto()
3872        TINYTEXT = auto()
3873        TIME = auto()
3874        TIMETZ = auto()
3875        TIMESTAMP = auto()
3876        TIMESTAMPLTZ = auto()
3877        TIMESTAMPTZ = auto()
3878        TIMESTAMP_S = auto()
3879        TIMESTAMP_MS = auto()
3880        TIMESTAMP_NS = auto()
3881        TINYINT = auto()
3882        TSMULTIRANGE = auto()
3883        TSRANGE = auto()
3884        TSTZMULTIRANGE = auto()
3885        TSTZRANGE = auto()
3886        UBIGINT = auto()
3887        UINT = auto()
3888        UINT128 = auto()
3889        UINT256 = auto()
3890        UMEDIUMINT = auto()
3891        UDECIMAL = auto()
3892        UNIQUEIDENTIFIER = auto()
3893        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3894        USERDEFINED = "USER-DEFINED"
3895        USMALLINT = auto()
3896        UTINYINT = auto()
3897        UUID = auto()
3898        VARBINARY = auto()
3899        VARCHAR = auto()
3900        VARIANT = auto()
3901        XML = auto()
3902        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4055class PseudoType(DataType):
4056    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4060class ObjectIdentifier(DataType):
4061    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4065class SubqueryPredicate(Predicate):
4066    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4069class All(SubqueryPredicate):
4070    pass
key = 'all'
class Any(SubqueryPredicate):
4073class Any(SubqueryPredicate):
4074    pass
key = 'any'
class Exists(SubqueryPredicate):
4077class Exists(SubqueryPredicate):
4078    pass
key = 'exists'
class Command(Expression):
4083class Command(Expression):
4084    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4087class Transaction(Expression):
4088    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4091class Commit(Expression):
4092    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4095class Rollback(Expression):
4096    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4099class AlterTable(Expression):
4100    arg_types = {
4101        "this": True,
4102        "actions": True,
4103        "exists": False,
4104        "only": False,
4105        "options": False,
4106    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4109class AddConstraint(Expression):
4110    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4113class DropPartition(Expression):
4114    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4118class Binary(Condition):
4119    arg_types = {"this": True, "expression": True}
4120
4121    @property
4122    def left(self) -> Expression:
4123        return self.this
4124
4125    @property
4126    def right(self) -> Expression:
4127        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4121    @property
4122    def left(self) -> Expression:
4123        return self.this
right: Expression
4125    @property
4126    def right(self) -> Expression:
4127        return self.expression
key = 'binary'
class Add(Binary):
4130class Add(Binary):
4131    pass
key = 'add'
class Connector(Binary):
4134class Connector(Binary):
4135    pass
key = 'connector'
class And(Connector):
4138class And(Connector):
4139    pass
key = 'and'
class Or(Connector):
4142class Or(Connector):
4143    pass
key = 'or'
class BitwiseAnd(Binary):
4146class BitwiseAnd(Binary):
4147    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4150class BitwiseLeftShift(Binary):
4151    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4154class BitwiseOr(Binary):
4155    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4158class BitwiseRightShift(Binary):
4159    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4162class BitwiseXor(Binary):
4163    pass
key = 'bitwisexor'
class Div(Binary):
4166class Div(Binary):
4167    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
arg_types = {'this': True, 'expression': True, 'typed': False, 'safe': False}
key = 'div'
class Overlaps(Binary):
4170class Overlaps(Binary):
4171    pass
key = 'overlaps'
class Dot(Binary):
4174class Dot(Binary):
4175    @property
4176    def is_star(self) -> bool:
4177        return self.expression.is_star
4178
4179    @property
4180    def name(self) -> str:
4181        return self.expression.name
4182
4183    @property
4184    def output_name(self) -> str:
4185        return self.name
4186
4187    @classmethod
4188    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4189        """Build a Dot object with a sequence of expressions."""
4190        if len(expressions) < 2:
4191            raise ValueError("Dot requires >= 2 expressions.")
4192
4193        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4194
4195    @property
4196    def parts(self) -> t.List[Expression]:
4197        """Return the parts of a table / column in order catalog, db, table."""
4198        this, *parts = self.flatten()
4199
4200        parts.reverse()
4201
4202        for arg in ("this", "table", "db", "catalog"):
4203            part = this.args.get(arg)
4204
4205            if isinstance(part, Expression):
4206                parts.append(part)
4207
4208        parts.reverse()
4209        return parts
is_star: bool
4175    @property
4176    def is_star(self) -> bool:
4177        return self.expression.is_star

Checks whether an expression is a star.

name: str
4179    @property
4180    def name(self) -> str:
4181        return self.expression.name
output_name: str
4183    @property
4184    def output_name(self) -> str:
4185        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
@classmethod
def build( self, expressions: Sequence[Expression]) -> Dot:
4187    @classmethod
4188    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4189        """Build a Dot object with a sequence of expressions."""
4190        if len(expressions) < 2:
4191            raise ValueError("Dot requires >= 2 expressions.")
4192
4193        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
4195    @property
4196    def parts(self) -> t.List[Expression]:
4197        """Return the parts of a table / column in order catalog, db, table."""
4198        this, *parts = self.flatten()
4199
4200        parts.reverse()
4201
4202        for arg in ("this", "table", "db", "catalog"):
4203            part = this.args.get(arg)
4204
4205            if isinstance(part, Expression):
4206                parts.append(part)
4207
4208        parts.reverse()
4209        return parts

Return the parts of a table / column in order catalog, db, table.

key = 'dot'
class DPipe(Binary):
4212class DPipe(Binary):
4213    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4216class EQ(Binary, Predicate):
4217    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4220class NullSafeEQ(Binary, Predicate):
4221    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4224class NullSafeNEQ(Binary, Predicate):
4225    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4229class PropertyEQ(Binary):
4230    pass
key = 'propertyeq'
class Distance(Binary):
4233class Distance(Binary):
4234    pass
key = 'distance'
class Escape(Binary):
4237class Escape(Binary):
4238    pass
key = 'escape'
class Glob(Binary, Predicate):
4241class Glob(Binary, Predicate):
4242    pass
key = 'glob'
class GT(Binary, Predicate):
4245class GT(Binary, Predicate):
4246    pass
key = 'gt'
class GTE(Binary, Predicate):
4249class GTE(Binary, Predicate):
4250    pass
key = 'gte'
class ILike(Binary, Predicate):
4253class ILike(Binary, Predicate):
4254    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4257class ILikeAny(Binary, Predicate):
4258    pass
key = 'ilikeany'
class IntDiv(Binary):
4261class IntDiv(Binary):
4262    pass
key = 'intdiv'
class Is(Binary, Predicate):
4265class Is(Binary, Predicate):
4266    pass
key = 'is'
class Kwarg(Binary):
4269class Kwarg(Binary):
4270    """Kwarg in special functions like func(kwarg => y)."""

Kwarg in special functions like func(kwarg => y).

key = 'kwarg'
class Like(Binary, Predicate):
4273class Like(Binary, Predicate):
4274    pass
key = 'like'
class LikeAny(Binary, Predicate):
4277class LikeAny(Binary, Predicate):
4278    pass
key = 'likeany'
class LT(Binary, Predicate):
4281class LT(Binary, Predicate):
4282    pass
key = 'lt'
class LTE(Binary, Predicate):
4285class LTE(Binary, Predicate):
4286    pass
key = 'lte'
class Mod(Binary):
4289class Mod(Binary):
4290    pass
key = 'mod'
class Mul(Binary):
4293class Mul(Binary):
4294    pass
key = 'mul'
class NEQ(Binary, Predicate):
4297class NEQ(Binary, Predicate):
4298    pass
key = 'neq'
class Operator(Binary):
4302class Operator(Binary):
4303    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4306class SimilarTo(Binary, Predicate):
4307    pass
key = 'similarto'
class Slice(Binary):
4310class Slice(Binary):
4311    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4314class Sub(Binary):
4315    pass
key = 'sub'
class Unary(Condition):
4320class Unary(Condition):
4321    pass
key = 'unary'
class BitwiseNot(Unary):
4324class BitwiseNot(Unary):
4325    pass
key = 'bitwisenot'
class Not(Unary):
4328class Not(Unary):
4329    pass
key = 'not'
class Paren(Unary):
4332class Paren(Unary):
4333    @property
4334    def output_name(self) -> str:
4335        return self.this.name
output_name: str
4333    @property
4334    def output_name(self) -> str:
4335        return self.this.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'paren'
class Neg(Unary):
4338class Neg(Unary):
4339    pass
key = 'neg'
class Alias(Expression):
4342class Alias(Expression):
4343    arg_types = {"this": True, "alias": False}
4344
4345    @property
4346    def output_name(self) -> str:
4347        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4345    @property
4346    def output_name(self) -> str:
4347        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'alias'
class PivotAlias(Alias):
4352class PivotAlias(Alias):
4353    pass
key = 'pivotalias'
class Aliases(Expression):
4356class Aliases(Expression):
4357    arg_types = {"this": True, "expressions": True}
4358
4359    @property
4360    def aliases(self):
4361        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4359    @property
4360    def aliases(self):
4361        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4365class AtIndex(Expression):
4366    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4369class AtTimeZone(Expression):
4370    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4373class FromTimeZone(Expression):
4374    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4377class Between(Predicate):
4378    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4381class Bracket(Condition):
4382    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4383    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4384
4385    @property
4386    def output_name(self) -> str:
4387        if len(self.expressions) == 1:
4388            return self.expressions[0].output_name
4389
4390        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4385    @property
4386    def output_name(self) -> str:
4387        if len(self.expressions) == 1:
4388            return self.expressions[0].output_name
4389
4390        return super().output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'bracket'
class Distinct(Expression):
4393class Distinct(Expression):
4394    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4397class In(Predicate):
4398    arg_types = {
4399        "this": True,
4400        "expressions": False,
4401        "query": False,
4402        "unnest": False,
4403        "field": False,
4404        "is_global": False,
4405    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4409class ForIn(Expression):
4410    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4413class TimeUnit(Expression):
4414    """Automatically converts unit arg into a var."""
4415
4416    arg_types = {"unit": False}
4417
4418    UNABBREVIATED_UNIT_NAME = {
4419        "D": "DAY",
4420        "H": "HOUR",
4421        "M": "MINUTE",
4422        "MS": "MILLISECOND",
4423        "NS": "NANOSECOND",
4424        "Q": "QUARTER",
4425        "S": "SECOND",
4426        "US": "MICROSECOND",
4427        "W": "WEEK",
4428        "Y": "YEAR",
4429    }
4430
4431    VAR_LIKE = (Column, Literal, Var)
4432
4433    def __init__(self, **args):
4434        unit = args.get("unit")
4435        if isinstance(unit, self.VAR_LIKE):
4436            args["unit"] = Var(
4437                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4438            )
4439        elif isinstance(unit, Week):
4440            unit.set("this", Var(this=unit.this.name.upper()))
4441
4442        super().__init__(**args)
4443
4444    @property
4445    def unit(self) -> t.Optional[Var]:
4446        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4433    def __init__(self, **args):
4434        unit = args.get("unit")
4435        if isinstance(unit, self.VAR_LIKE):
4436            args["unit"] = Var(
4437                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4438            )
4439        elif isinstance(unit, Week):
4440            unit.set("this", Var(this=unit.this.name.upper()))
4441
4442        super().__init__(**args)
arg_types = {'unit': False}
UNABBREVIATED_UNIT_NAME = {'D': 'DAY', 'H': 'HOUR', 'M': 'MINUTE', 'MS': 'MILLISECOND', 'NS': 'NANOSECOND', 'Q': 'QUARTER', 'S': 'SECOND', 'US': 'MICROSECOND', 'W': 'WEEK', 'Y': 'YEAR'}
VAR_LIKE = (<class 'Column'>, <class 'Literal'>, <class 'Var'>)
unit: Optional[Var]
4444    @property
4445    def unit(self) -> t.Optional[Var]:
4446        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4449class IntervalOp(TimeUnit):
4450    arg_types = {"unit": True, "expression": True}
4451
4452    def interval(self):
4453        return Interval(
4454            this=self.expression.copy(),
4455            unit=self.unit.copy(),
4456        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4452    def interval(self):
4453        return Interval(
4454            this=self.expression.copy(),
4455            unit=self.unit.copy(),
4456        )
key = 'intervalop'
class IntervalSpan(DataType):
4462class IntervalSpan(DataType):
4463    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4466class Interval(TimeUnit):
4467    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4470class IgnoreNulls(Expression):
4471    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4474class RespectNulls(Expression):
4475    pass
key = 'respectnulls'
class HavingMax(Expression):
4479class HavingMax(Expression):
4480    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4484class Func(Condition):
4485    """
4486    The base class for all function expressions.
4487
4488    Attributes:
4489        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4490            treated as a variable length argument and the argument's value will be stored as a list.
4491        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4492            function expression. These values are used to map this node to a name during parsing as
4493            well as to provide the function's name during SQL string generation. By default the SQL
4494            name is set to the expression's class name transformed to snake case.
4495    """
4496
4497    is_var_len_args = False
4498
4499    @classmethod
4500    def from_arg_list(cls, args):
4501        if cls.is_var_len_args:
4502            all_arg_keys = list(cls.arg_types)
4503            # If this function supports variable length argument treat the last argument as such.
4504            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4505            num_non_var = len(non_var_len_arg_keys)
4506
4507            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4508            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4509        else:
4510            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4511
4512        return cls(**args_dict)
4513
4514    @classmethod
4515    def sql_names(cls):
4516        if cls is Func:
4517            raise NotImplementedError(
4518                "SQL name is only supported by concrete function implementations"
4519            )
4520        if "_sql_names" not in cls.__dict__:
4521            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4522        return cls._sql_names
4523
4524    @classmethod
4525    def sql_name(cls):
4526        return cls.sql_names()[0]
4527
4528    @classmethod
4529    def default_parser_mappings(cls):
4530        return {name: cls.from_arg_list for name in cls.sql_names()}

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
4499    @classmethod
4500    def from_arg_list(cls, args):
4501        if cls.is_var_len_args:
4502            all_arg_keys = list(cls.arg_types)
4503            # If this function supports variable length argument treat the last argument as such.
4504            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4505            num_non_var = len(non_var_len_arg_keys)
4506
4507            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4508            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4509        else:
4510            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4511
4512        return cls(**args_dict)
@classmethod
def sql_names(cls):
4514    @classmethod
4515    def sql_names(cls):
4516        if cls is Func:
4517            raise NotImplementedError(
4518                "SQL name is only supported by concrete function implementations"
4519            )
4520        if "_sql_names" not in cls.__dict__:
4521            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4522        return cls._sql_names
@classmethod
def sql_name(cls):
4524    @classmethod
4525    def sql_name(cls):
4526        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4528    @classmethod
4529    def default_parser_mappings(cls):
4530        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4533class AggFunc(Func):
4534    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4537class ParameterizedAgg(AggFunc):
4538    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4541class Abs(Func):
4542    pass
key = 'abs'
class ArgMax(AggFunc):
4545class ArgMax(AggFunc):
4546    arg_types = {"this": True, "expression": True, "count": False}
4547    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4550class ArgMin(AggFunc):
4551    arg_types = {"this": True, "expression": True, "count": False}
4552    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4555class ApproxTopK(AggFunc):
4556    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4559class Flatten(Func):
4560    pass
key = 'flatten'
class Transform(Func):
4564class Transform(Func):
4565    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4568class Anonymous(Func):
4569    arg_types = {"this": True, "expressions": False}
4570    is_var_len_args = True
4571
4572    @property
4573    def name(self) -> str:
4574        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
4572    @property
4573    def name(self) -> str:
4574        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4577class AnonymousAggFunc(AggFunc):
4578    arg_types = {"this": True, "expressions": False}
4579    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4583class CombinedAggFunc(AnonymousAggFunc):
4584    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4587class CombinedParameterizedAgg(ParameterizedAgg):
4588    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
4593class Hll(AggFunc):
4594    arg_types = {"this": True, "expressions": False}
4595    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4598class ApproxDistinct(AggFunc):
4599    arg_types = {"this": True, "accuracy": False}
4600    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4603class Array(Func):
4604    arg_types = {"expressions": False}
4605    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4609class ToArray(Func):
4610    pass
key = 'toarray'
class ToChar(Func):
4615class ToChar(Func):
4616    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4621class ToNumber(Func):
4622    arg_types = {
4623        "this": True,
4624        "format": False,
4625        "nlsparam": False,
4626        "precision": False,
4627        "scale": False,
4628    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4632class Convert(Func):
4633    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4636class GenerateSeries(Func):
4637    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4640class ArrayAgg(AggFunc):
4641    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4644class ArrayUniqueAgg(AggFunc):
4645    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4648class ArrayAll(Func):
4649    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4653class ArrayAny(Func):
4654    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4657class ArrayConcat(Func):
4658    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4659    arg_types = {"this": True, "expressions": False}
4660    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4663class ArrayContains(Binary, Func):
4664    pass
key = 'arraycontains'
class ArrayContained(Binary):
4667class ArrayContained(Binary):
4668    pass
key = 'arraycontained'
class ArrayFilter(Func):
4671class ArrayFilter(Func):
4672    arg_types = {"this": True, "expression": True}
4673    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4676class ArrayToString(Func):
4677    arg_types = {"this": True, "expression": True, "null": False}
4678    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4681class ArrayOverlaps(Binary, Func):
4682    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4685class ArraySize(Func):
4686    arg_types = {"this": True, "expression": False}
4687    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4690class ArraySort(Func):
4691    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4694class ArraySum(Func):
4695    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4698class ArrayUnionAgg(AggFunc):
4699    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4702class Avg(AggFunc):
4703    pass
key = 'avg'
class AnyValue(AggFunc):
4706class AnyValue(AggFunc):
4707    pass
key = 'anyvalue'
class Lag(AggFunc):
4710class Lag(AggFunc):
4711    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4714class Lead(AggFunc):
4715    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4720class First(AggFunc):
4721    pass
key = 'first'
class Last(AggFunc):
4724class Last(AggFunc):
4725    pass
key = 'last'
class FirstValue(AggFunc):
4728class FirstValue(AggFunc):
4729    pass
key = 'firstvalue'
class LastValue(AggFunc):
4732class LastValue(AggFunc):
4733    pass
key = 'lastvalue'
class NthValue(AggFunc):
4736class NthValue(AggFunc):
4737    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4740class Case(Func):
4741    arg_types = {"this": False, "ifs": True, "default": False}
4742
4743    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4744        instance = maybe_copy(self, copy)
4745        instance.append(
4746            "ifs",
4747            If(
4748                this=maybe_parse(condition, copy=copy, **opts),
4749                true=maybe_parse(then, copy=copy, **opts),
4750            ),
4751        )
4752        return instance
4753
4754    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4755        instance = maybe_copy(self, copy)
4756        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4757        return instance
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
4743    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4744        instance = maybe_copy(self, copy)
4745        instance.append(
4746            "ifs",
4747            If(
4748                this=maybe_parse(condition, copy=copy, **opts),
4749                true=maybe_parse(then, copy=copy, **opts),
4750            ),
4751        )
4752        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4754    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4755        instance = maybe_copy(self, copy)
4756        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4757        return instance
key = 'case'
class Cast(Func):
4760class Cast(Func):
4761    arg_types = {
4762        "this": True,
4763        "to": True,
4764        "format": False,
4765        "safe": False,
4766        "action": False,
4767    }
4768
4769    @property
4770    def name(self) -> str:
4771        return self.this.name
4772
4773    @property
4774    def to(self) -> DataType:
4775        return self.args["to"]
4776
4777    @property
4778    def output_name(self) -> str:
4779        return self.name
4780
4781    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4782        """
4783        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4784        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4785        array<int> != array<float>.
4786
4787        Args:
4788            dtypes: the data types to compare this Cast's DataType to.
4789
4790        Returns:
4791            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4792        """
4793        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4769    @property
4770    def name(self) -> str:
4771        return self.this.name
to: DataType
4773    @property
4774    def to(self) -> DataType:
4775        return self.args["to"]
output_name: str
4777    @property
4778    def output_name(self) -> str:
4779        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4781    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4782        """
4783        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4784        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4785        array<int> != array<float>.
4786
4787        Args:
4788            dtypes: the data types to compare this Cast's DataType to.
4789
4790        Returns:
4791            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4792        """
4793        return self.to.is_type(*dtypes)

Checks whether this Cast's DataType matches one of the provided data types. Nested types like arrays or structs will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this Cast's DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this Cast's DataType.

key = 'cast'
class TryCast(Cast):
4796class TryCast(Cast):
4797    pass
key = 'trycast'
class CastToStrType(Func):
4800class CastToStrType(Func):
4801    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4804class Collate(Binary, Func):
4805    pass
key = 'collate'
class Ceil(Func):
4808class Ceil(Func):
4809    arg_types = {"this": True, "decimals": False}
4810    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4813class Coalesce(Func):
4814    arg_types = {"this": True, "expressions": False}
4815    is_var_len_args = True
4816    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4819class Chr(Func):
4820    arg_types = {"this": True, "charset": False, "expressions": False}
4821    is_var_len_args = True
4822    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4825class Concat(Func):
4826    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4827    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4830class ConcatWs(Concat):
4831    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4835class ConnectByRoot(Func):
4836    pass
key = 'connectbyroot'
class Count(AggFunc):
4839class Count(AggFunc):
4840    arg_types = {"this": False, "expressions": False}
4841    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4844class CountIf(AggFunc):
4845    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4849class Cbrt(Func):
4850    pass
key = 'cbrt'
class CurrentDate(Func):
4853class CurrentDate(Func):
4854    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4857class CurrentDatetime(Func):
4858    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4861class CurrentTime(Func):
4862    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4865class CurrentTimestamp(Func):
4866    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4869class CurrentUser(Func):
4870    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4873class DateAdd(Func, IntervalOp):
4874    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4877class DateSub(Func, IntervalOp):
4878    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4881class DateDiff(Func, TimeUnit):
4882    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4883    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4886class DateTrunc(Func):
4887    arg_types = {"unit": True, "this": True, "zone": False}
4888
4889    def __init__(self, **args):
4890        unit = args.get("unit")
4891        if isinstance(unit, TimeUnit.VAR_LIKE):
4892            args["unit"] = Literal.string(
4893                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4894            )
4895        elif isinstance(unit, Week):
4896            unit.set("this", Literal.string(unit.this.name.upper()))
4897
4898        super().__init__(**args)
4899
4900    @property
4901    def unit(self) -> Expression:
4902        return self.args["unit"]
DateTrunc(**args)
4889    def __init__(self, **args):
4890        unit = args.get("unit")
4891        if isinstance(unit, TimeUnit.VAR_LIKE):
4892            args["unit"] = Literal.string(
4893                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4894            )
4895        elif isinstance(unit, Week):
4896            unit.set("this", Literal.string(unit.this.name.upper()))
4897
4898        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4900    @property
4901    def unit(self) -> Expression:
4902        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4905class DatetimeAdd(Func, IntervalOp):
4906    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4909class DatetimeSub(Func, IntervalOp):
4910    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4913class DatetimeDiff(Func, TimeUnit):
4914    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4917class DatetimeTrunc(Func, TimeUnit):
4918    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4921class DayOfWeek(Func):
4922    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4925class DayOfMonth(Func):
4926    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4929class DayOfYear(Func):
4930    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4933class ToDays(Func):
4934    pass
key = 'todays'
class WeekOfYear(Func):
4937class WeekOfYear(Func):
4938    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4941class MonthsBetween(Func):
4942    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4945class LastDay(Func, TimeUnit):
4946    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4947    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4950class Extract(Func):
4951    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4954class Timestamp(Func):
4955    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4958class TimestampAdd(Func, TimeUnit):
4959    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4962class TimestampSub(Func, TimeUnit):
4963    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4966class TimestampDiff(Func, TimeUnit):
4967    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4968    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4971class TimestampTrunc(Func, TimeUnit):
4972    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4975class TimeAdd(Func, TimeUnit):
4976    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4979class TimeSub(Func, TimeUnit):
4980    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4983class TimeDiff(Func, TimeUnit):
4984    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4987class TimeTrunc(Func, TimeUnit):
4988    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4991class DateFromParts(Func):
4992    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4993    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4996class TimeFromParts(Func):
4997    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4998    arg_types = {
4999        "hour": True,
5000        "min": True,
5001        "sec": True,
5002        "nano": False,
5003        "fractions": False,
5004        "precision": False,
5005    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5008class DateStrToDate(Func):
5009    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5012class DateToDateStr(Func):
5013    pass
key = 'datetodatestr'
class DateToDi(Func):
5016class DateToDi(Func):
5017    pass
key = 'datetodi'
class Date(Func):
5021class Date(Func):
5022    arg_types = {"this": False, "zone": False, "expressions": False}
5023    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5026class Day(Func):
5027    pass
key = 'day'
class Decode(Func):
5030class Decode(Func):
5031    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5034class DiToDate(Func):
5035    pass
key = 'ditodate'
class Encode(Func):
5038class Encode(Func):
5039    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5042class Exp(Func):
5043    pass
key = 'exp'
class Explode(Func):
5047class Explode(Func):
5048    arg_types = {"this": True, "expressions": False}
5049    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5052class ExplodeOuter(Explode):
5053    pass
key = 'explodeouter'
class Posexplode(Explode):
5056class Posexplode(Explode):
5057    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5060class PosexplodeOuter(Posexplode, ExplodeOuter):
5061    pass
key = 'posexplodeouter'
class Floor(Func):
5064class Floor(Func):
5065    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5068class FromBase64(Func):
5069    pass
key = 'frombase64'
class ToBase64(Func):
5072class ToBase64(Func):
5073    pass
key = 'tobase64'
class GenerateDateArray(Func):
5076class GenerateDateArray(Func):
5077    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5080class Greatest(Func):
5081    arg_types = {"this": True, "expressions": False}
5082    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5085class GroupConcat(AggFunc):
5086    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5089class Hex(Func):
5090    pass
key = 'hex'
class Xor(Connector, Func):
5093class Xor(Connector, Func):
5094    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5097class If(Func):
5098    arg_types = {"this": True, "true": True, "false": False}
5099    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5102class Nullif(Func):
5103    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5106class Initcap(Func):
5107    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5110class IsNan(Func):
5111    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5114class IsInf(Func):
5115    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5118class JSONPath(Expression):
5119    arg_types = {"expressions": True}
5120
5121    @property
5122    def output_name(self) -> str:
5123        last_segment = self.expressions[-1].this
5124        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5121    @property
5122    def output_name(self) -> str:
5123        last_segment = self.expressions[-1].this
5124        return last_segment if isinstance(last_segment, str) else ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonpath'
class JSONPathPart(Expression):
5127class JSONPathPart(Expression):
5128    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5131class JSONPathFilter(JSONPathPart):
5132    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5135class JSONPathKey(JSONPathPart):
5136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5139class JSONPathRecursive(JSONPathPart):
5140    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5143class JSONPathRoot(JSONPathPart):
5144    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5147class JSONPathScript(JSONPathPart):
5148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5151class JSONPathSlice(JSONPathPart):
5152    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5155class JSONPathSelector(JSONPathPart):
5156    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5159class JSONPathSubscript(JSONPathPart):
5160    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5163class JSONPathUnion(JSONPathPart):
5164    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5167class JSONPathWildcard(JSONPathPart):
5168    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5171class FormatJson(Expression):
5172    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5175class JSONKeyValue(Expression):
5176    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5179class JSONObject(Func):
5180    arg_types = {
5181        "expressions": False,
5182        "null_handling": False,
5183        "unique_keys": False,
5184        "return_type": False,
5185        "encoding": False,
5186    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5189class JSONObjectAgg(AggFunc):
5190    arg_types = {
5191        "expressions": False,
5192        "null_handling": False,
5193        "unique_keys": False,
5194        "return_type": False,
5195        "encoding": False,
5196    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5200class JSONArray(Func):
5201    arg_types = {
5202        "expressions": True,
5203        "null_handling": False,
5204        "return_type": False,
5205        "strict": False,
5206    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5210class JSONArrayAgg(Func):
5211    arg_types = {
5212        "this": True,
5213        "order": False,
5214        "null_handling": False,
5215        "return_type": False,
5216        "strict": False,
5217    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5222class JSONColumnDef(Expression):
5223    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
5226class JSONSchema(Expression):
5227    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5231class JSONTable(Func):
5232    arg_types = {
5233        "this": True,
5234        "schema": True,
5235        "path": False,
5236        "error_handling": False,
5237        "empty_handling": False,
5238    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5241class OpenJSONColumnDef(Expression):
5242    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key = 'openjsoncolumndef'
class OpenJSON(Func):
5245class OpenJSON(Func):
5246    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5249class JSONBContains(Binary):
5250    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5253class JSONExtract(Binary, Func):
5254    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5255    _sql_names = ["JSON_EXTRACT"]
5256    is_var_len_args = True
5257
5258    @property
5259    def output_name(self) -> str:
5260        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5258    @property
5259    def output_name(self) -> str:
5260        return self.expression.output_name if not self.expressions else ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractScalar(Binary, Func):
5263class JSONExtractScalar(Binary, Func):
5264    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5265    _sql_names = ["JSON_EXTRACT_SCALAR"]
5266    is_var_len_args = True
5267
5268    @property
5269    def output_name(self) -> str:
5270        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5268    @property
5269    def output_name(self) -> str:
5270        return self.expression.output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
5273class JSONBExtract(Binary, Func):
5274    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5277class JSONBExtractScalar(Binary, Func):
5278    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5281class JSONFormat(Func):
5282    arg_types = {"this": False, "options": False}
5283    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5287class JSONArrayContains(Binary, Predicate, Func):
5288    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5291class ParseJSON(Func):
5292    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5293    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5294    arg_types = {"this": True, "expressions": False}
5295    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5298class Least(Func):
5299    arg_types = {"this": True, "expressions": False}
5300    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5303class Left(Func):
5304    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5311class Length(Func):
5312    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5315class Levenshtein(Func):
5316    arg_types = {
5317        "this": True,
5318        "expression": False,
5319        "ins_cost": False,
5320        "del_cost": False,
5321        "sub_cost": False,
5322    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5325class Ln(Func):
5326    pass
key = 'ln'
class Log(Func):
5329class Log(Func):
5330    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5333class LogicalOr(AggFunc):
5334    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5337class LogicalAnd(AggFunc):
5338    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5341class Lower(Func):
5342    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5345class Map(Func):
5346    arg_types = {"keys": False, "values": False}
5347
5348    @property
5349    def keys(self) -> t.List[Expression]:
5350        keys = self.args.get("keys")
5351        return keys.expressions if keys else []
5352
5353    @property
5354    def values(self) -> t.List[Expression]:
5355        values = self.args.get("values")
5356        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5348    @property
5349    def keys(self) -> t.List[Expression]:
5350        keys = self.args.get("keys")
5351        return keys.expressions if keys else []
values: List[Expression]
5353    @property
5354    def values(self) -> t.List[Expression]:
5355        values = self.args.get("values")
5356        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5360class ToMap(Func):
5361    pass
key = 'tomap'
class MapFromEntries(Func):
5364class MapFromEntries(Func):
5365    pass
key = 'mapfromentries'
class StarMap(Func):
5368class StarMap(Func):
5369    pass
key = 'starmap'
class VarMap(Func):
5372class VarMap(Func):
5373    arg_types = {"keys": True, "values": True}
5374    is_var_len_args = True
5375
5376    @property
5377    def keys(self) -> t.List[Expression]:
5378        return self.args["keys"].expressions
5379
5380    @property
5381    def values(self) -> t.List[Expression]:
5382        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5376    @property
5377    def keys(self) -> t.List[Expression]:
5378        return self.args["keys"].expressions
values: List[Expression]
5380    @property
5381    def values(self) -> t.List[Expression]:
5382        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5386class MatchAgainst(Func):
5387    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5390class Max(AggFunc):
5391    arg_types = {"this": True, "expressions": False}
5392    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5395class MD5(Func):
5396    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5400class MD5Digest(Func):
5401    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5404class Min(AggFunc):
5405    arg_types = {"this": True, "expressions": False}
5406    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5409class Month(Func):
5410    pass
key = 'month'
class AddMonths(Func):
5413class AddMonths(Func):
5414    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5417class Nvl2(Func):
5418    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5422class Predict(Func):
5423    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5426class Pow(Binary, Func):
5427    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5430class PercentileCont(AggFunc):
5431    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5434class PercentileDisc(AggFunc):
5435    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5438class Quantile(AggFunc):
5439    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5442class ApproxQuantile(Quantile):
5443    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Rand(Func):
5446class Rand(Func):
5447    _sql_names = ["RAND", "RANDOM"]
5448    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5451class Randn(Func):
5452    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5455class RangeN(Func):
5456    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5459class ReadCSV(Func):
5460    _sql_names = ["READ_CSV"]
5461    is_var_len_args = True
5462    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5465class Reduce(Func):
5466    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
arg_types = {'this': True, 'initial': True, 'merge': True, 'finish': False}
key = 'reduce'
class RegexpExtract(Func):
5469class RegexpExtract(Func):
5470    arg_types = {
5471        "this": True,
5472        "expression": True,
5473        "position": False,
5474        "occurrence": False,
5475        "parameters": False,
5476        "group": False,
5477    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5480class RegexpReplace(Func):
5481    arg_types = {
5482        "this": True,
5483        "expression": True,
5484        "replacement": False,
5485        "position": False,
5486        "occurrence": False,
5487        "parameters": False,
5488        "modifiers": False,
5489    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5492class RegexpLike(Binary, Func):
5493    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5496class RegexpILike(Binary, Func):
5497    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5502class RegexpSplit(Func):
5503    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5506class Repeat(Func):
5507    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5512class Round(Func):
5513    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5516class RowNumber(Func):
5517    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5520class SafeDivide(Func):
5521    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5524class SHA(Func):
5525    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5528class SHA2(Func):
5529    _sql_names = ["SHA2"]
5530    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5533class Sign(Func):
5534    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5537class SortArray(Func):
5538    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5541class Split(Func):
5542    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5547class Substring(Func):
5548    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5551class StandardHash(Func):
5552    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5555class StartsWith(Func):
5556    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5557    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5560class StrPosition(Func):
5561    arg_types = {
5562        "this": True,
5563        "substr": True,
5564        "position": False,
5565        "instance": False,
5566    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5569class StrToDate(Func):
5570    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5573class StrToTime(Func):
5574    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5579class StrToUnix(Func):
5580    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5585class StrToMap(Func):
5586    arg_types = {
5587        "this": True,
5588        "pair_delim": False,
5589        "key_value_delim": False,
5590        "duplicate_resolution_callback": False,
5591    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5594class NumberToStr(Func):
5595    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5598class FromBase(Func):
5599    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5602class Struct(Func):
5603    arg_types = {"expressions": False}
5604    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5607class StructExtract(Func):
5608    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5613class Stuff(Func):
5614    _sql_names = ["STUFF", "INSERT"]
5615    arg_types = {"this": True, "start": True, "length": True, "expression": True}
arg_types = {'this': True, 'start': True, 'length': True, 'expression': True}
key = 'stuff'
class Sum(AggFunc):
5618class Sum(AggFunc):
5619    pass
key = 'sum'
class Sqrt(Func):
5622class Sqrt(Func):
5623    pass
key = 'sqrt'
class Stddev(AggFunc):
5626class Stddev(AggFunc):
5627    pass
key = 'stddev'
class StddevPop(AggFunc):
5630class StddevPop(AggFunc):
5631    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5634class StddevSamp(AggFunc):
5635    pass
key = 'stddevsamp'
class TimeToStr(Func):
5638class TimeToStr(Func):
5639    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5642class TimeToTimeStr(Func):
5643    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5646class TimeToUnix(Func):
5647    pass
key = 'timetounix'
class TimeStrToDate(Func):
5650class TimeStrToDate(Func):
5651    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5654class TimeStrToTime(Func):
5655    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5658class TimeStrToUnix(Func):
5659    pass
key = 'timestrtounix'
class Trim(Func):
5662class Trim(Func):
5663    arg_types = {
5664        "this": True,
5665        "expression": False,
5666        "position": False,
5667        "collation": False,
5668    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5671class TsOrDsAdd(Func, TimeUnit):
5672    # return_type is used to correctly cast the arguments of this expression when transpiling it
5673    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5674
5675    @property
5676    def return_type(self) -> DataType:
5677        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
5675    @property
5676    def return_type(self) -> DataType:
5677        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5680class TsOrDsDiff(Func, TimeUnit):
5681    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5684class TsOrDsToDateStr(Func):
5685    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5688class TsOrDsToDate(Func):
5689    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5692class TsOrDsToTime(Func):
5693    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5696class TsOrDsToTimestamp(Func):
5697    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5700class TsOrDiToDi(Func):
5701    pass
key = 'tsorditodi'
class Unhex(Func):
5704class Unhex(Func):
5705    pass
key = 'unhex'
class UnixDate(Func):
5709class UnixDate(Func):
5710    pass
key = 'unixdate'
class UnixToStr(Func):
5713class UnixToStr(Func):
5714    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5719class UnixToTime(Func):
5720    arg_types = {
5721        "this": True,
5722        "scale": False,
5723        "zone": False,
5724        "hours": False,
5725        "minutes": False,
5726        "format": False,
5727    }
5728
5729    SECONDS = Literal.number(0)
5730    DECIS = Literal.number(1)
5731    CENTIS = Literal.number(2)
5732    MILLIS = Literal.number(3)
5733    DECIMILLIS = Literal.number(4)
5734    CENTIMILLIS = Literal.number(5)
5735    MICROS = Literal.number(6)
5736    DECIMICROS = Literal.number(7)
5737    CENTIMICROS = Literal.number(8)
5738    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False, 'format': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
5741class UnixToTimeStr(Func):
5742    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5745class TimestampFromParts(Func):
5746    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5747    arg_types = {
5748        "year": True,
5749        "month": True,
5750        "day": True,
5751        "hour": True,
5752        "min": True,
5753        "sec": True,
5754        "nano": False,
5755        "zone": False,
5756        "milli": False,
5757    }
arg_types = {'year': True, 'month': True, 'day': True, 'hour': True, 'min': True, 'sec': True, 'nano': False, 'zone': False, 'milli': False}
key = 'timestampfromparts'
class Upper(Func):
5760class Upper(Func):
5761    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5764class Corr(Binary, AggFunc):
5765    pass
key = 'corr'
class Variance(AggFunc):
5768class Variance(AggFunc):
5769    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5772class VariancePop(AggFunc):
5773    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5776class CovarSamp(Binary, AggFunc):
5777    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5780class CovarPop(Binary, AggFunc):
5781    pass
key = 'covarpop'
class Week(Func):
5784class Week(Func):
5785    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5788class XMLTable(Func):
5789    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
arg_types = {'this': True, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class Year(Func):
5792class Year(Func):
5793    pass
key = 'year'
class Use(Expression):
5796class Use(Expression):
5797    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5800class Merge(Expression):
5801    arg_types = {
5802        "this": True,
5803        "using": True,
5804        "on": True,
5805        "expressions": True,
5806        "with": False,
5807    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5810class When(Func):
5811    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class NextValueFor(Func):
5816class NextValueFor(Func):
5817    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5855def maybe_parse(
5856    sql_or_expression: ExpOrStr,
5857    *,
5858    into: t.Optional[IntoType] = None,
5859    dialect: DialectType = None,
5860    prefix: t.Optional[str] = None,
5861    copy: bool = False,
5862    **opts,
5863) -> Expression:
5864    """Gracefully handle a possible string or expression.
5865
5866    Example:
5867        >>> maybe_parse("1")
5868        Literal(this=1, is_string=False)
5869        >>> maybe_parse(to_identifier("x"))
5870        Identifier(this=x, quoted=False)
5871
5872    Args:
5873        sql_or_expression: the SQL code string or an expression
5874        into: the SQLGlot Expression to parse into
5875        dialect: the dialect used to parse the input expressions (in the case that an
5876            input expression is a SQL string).
5877        prefix: a string to prefix the sql with before it gets parsed
5878            (automatically includes a space)
5879        copy: whether to copy the expression.
5880        **opts: other options to use to parse the input expressions (again, in the case
5881            that an input expression is a SQL string).
5882
5883    Returns:
5884        Expression: the parsed or given expression.
5885    """
5886    if isinstance(sql_or_expression, Expression):
5887        if copy:
5888            return sql_or_expression.copy()
5889        return sql_or_expression
5890
5891    if sql_or_expression is None:
5892        raise ParseError("SQL cannot be None")
5893
5894    import sqlglot
5895
5896    sql = str(sql_or_expression)
5897    if prefix:
5898        sql = f"{prefix} {sql}"
5899
5900    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)

Gracefully handle a possible string or expression.

Example:
>>> maybe_parse("1")
Literal(this=1, is_string=False)
>>> maybe_parse(to_identifier("x"))
Identifier(this=x, quoted=False)
Arguments:
  • sql_or_expression: the SQL code string or an expression
  • into: the SQLGlot Expression to parse into
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • prefix: a string to prefix the sql with before it gets parsed (automatically includes a space)
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Expression: the parsed or given expression.

def maybe_copy(instance, copy=True):
5911def maybe_copy(instance, copy=True):
5912    return instance.copy() if copy and instance else instance
def union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
6126def union(
6127    left: ExpOrStr,
6128    right: ExpOrStr,
6129    distinct: bool = True,
6130    dialect: DialectType = None,
6131    copy: bool = True,
6132    **opts,
6133) -> Union:
6134    """
6135    Initializes a syntax tree from one UNION expression.
6136
6137    Example:
6138        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6139        'SELECT * FROM foo UNION SELECT * FROM bla'
6140
6141    Args:
6142        left: the SQL code string corresponding to the left-hand side.
6143            If an `Expression` instance is passed, it will be used as-is.
6144        right: the SQL code string corresponding to the right-hand side.
6145            If an `Expression` instance is passed, it will be used as-is.
6146        distinct: set the DISTINCT flag if and only if this is true.
6147        dialect: the dialect used to parse the input expression.
6148        copy: whether to copy the expression.
6149        opts: other options to use to parse the input expressions.
6150
6151    Returns:
6152        The new Union instance.
6153    """
6154    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6155    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6156
6157    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
6160def intersect(
6161    left: ExpOrStr,
6162    right: ExpOrStr,
6163    distinct: bool = True,
6164    dialect: DialectType = None,
6165    copy: bool = True,
6166    **opts,
6167) -> Intersect:
6168    """
6169    Initializes a syntax tree from one INTERSECT expression.
6170
6171    Example:
6172        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6173        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6174
6175    Args:
6176        left: the SQL code string corresponding to the left-hand side.
6177            If an `Expression` instance is passed, it will be used as-is.
6178        right: the SQL code string corresponding to the right-hand side.
6179            If an `Expression` instance is passed, it will be used as-is.
6180        distinct: set the DISTINCT flag if and only if this is true.
6181        dialect: the dialect used to parse the input expression.
6182        copy: whether to copy the expression.
6183        opts: other options to use to parse the input expressions.
6184
6185    Returns:
6186        The new Intersect instance.
6187    """
6188    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6189    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6190
6191    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
6194def except_(
6195    left: ExpOrStr,
6196    right: ExpOrStr,
6197    distinct: bool = True,
6198    dialect: DialectType = None,
6199    copy: bool = True,
6200    **opts,
6201) -> Except:
6202    """
6203    Initializes a syntax tree from one EXCEPT expression.
6204
6205    Example:
6206        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6207        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6208
6209    Args:
6210        left: the SQL code string corresponding to the left-hand side.
6211            If an `Expression` instance is passed, it will be used as-is.
6212        right: the SQL code string corresponding to the right-hand side.
6213            If an `Expression` instance is passed, it will be used as-is.
6214        distinct: set the DISTINCT flag if and only if this is true.
6215        dialect: the dialect used to parse the input expression.
6216        copy: whether to copy the expression.
6217        opts: other options to use to parse the input expressions.
6218
6219    Returns:
6220        The new Except instance.
6221    """
6222    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6223    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6224
6225    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6228def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6229    """
6230    Initializes a syntax tree from one or multiple SELECT expressions.
6231
6232    Example:
6233        >>> select("col1", "col2").from_("tbl").sql()
6234        'SELECT col1, col2 FROM tbl'
6235
6236    Args:
6237        *expressions: the SQL code string to parse as the expressions of a
6238            SELECT statement. If an Expression instance is passed, this is used as-is.
6239        dialect: the dialect used to parse the input expressions (in the case that an
6240            input expression is a SQL string).
6241        **opts: other options to use to parse the input expressions (again, in the case
6242            that an input expression is a SQL string).
6243
6244    Returns:
6245        Select: the syntax tree for the SELECT statement.
6246    """
6247    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

Example:
>>> select("col1", "col2").from_("tbl").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expressions: the SQL code string to parse as the expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6250def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6251    """
6252    Initializes a syntax tree from a FROM expression.
6253
6254    Example:
6255        >>> from_("tbl").select("col1", "col2").sql()
6256        'SELECT col1, col2 FROM tbl'
6257
6258    Args:
6259        *expression: the SQL code string to parse as the FROM expressions of a
6260            SELECT statement. If an Expression instance is passed, this is used as-is.
6261        dialect: the dialect used to parse the input expression (in the case that the
6262            input expression is a SQL string).
6263        **opts: other options to use to parse the input expressions (again, in the case
6264            that the input expression is a SQL string).
6265
6266    Returns:
6267        Select: the syntax tree for the SELECT statement.
6268    """
6269    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

Example:
>>> from_("tbl").select("col1", "col2").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expression: the SQL code string to parse as the FROM expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: dict, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
6272def update(
6273    table: str | Table,
6274    properties: dict,
6275    where: t.Optional[ExpOrStr] = None,
6276    from_: t.Optional[ExpOrStr] = None,
6277    dialect: DialectType = None,
6278    **opts,
6279) -> Update:
6280    """
6281    Creates an update statement.
6282
6283    Example:
6284        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6285        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6286
6287    Args:
6288        *properties: dictionary of properties to set which are
6289            auto converted to sql objects eg None -> NULL
6290        where: sql conditional parsed into a WHERE statement
6291        from_: sql statement parsed into a FROM statement
6292        dialect: the dialect used to parse the input expressions.
6293        **opts: other options to use to parse the input expressions.
6294
6295    Returns:
6296        Update: the syntax tree for the UPDATE statement.
6297    """
6298    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6299    update_expr.set(
6300        "expressions",
6301        [
6302            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6303            for k, v in properties.items()
6304        ],
6305    )
6306    if from_:
6307        update_expr.set(
6308            "from",
6309            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6310        )
6311    if isinstance(where, Condition):
6312        where = Where(this=where)
6313    if where:
6314        update_expr.set(
6315            "where",
6316            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6317        )
6318    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
"UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
Arguments:
  • *properties: dictionary of properties to set which are auto converted to sql objects eg None -> NULL
  • where: sql conditional parsed into a WHERE statement
  • from_: sql statement parsed into a FROM statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
6321def delete(
6322    table: ExpOrStr,
6323    where: t.Optional[ExpOrStr] = None,
6324    returning: t.Optional[ExpOrStr] = None,
6325    dialect: DialectType = None,
6326    **opts,
6327) -> Delete:
6328    """
6329    Builds a delete statement.
6330
6331    Example:
6332        >>> delete("my_table", where="id > 1").sql()
6333        'DELETE FROM my_table WHERE id > 1'
6334
6335    Args:
6336        where: sql conditional parsed into a WHERE statement
6337        returning: sql conditional parsed into a RETURNING statement
6338        dialect: the dialect used to parse the input expressions.
6339        **opts: other options to use to parse the input expressions.
6340
6341    Returns:
6342        Delete: the syntax tree for the DELETE statement.
6343    """
6344    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6345    if where:
6346        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6347    if returning:
6348        delete_expr = t.cast(
6349            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6350        )
6351    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
6354def insert(
6355    expression: ExpOrStr,
6356    into: ExpOrStr,
6357    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6358    overwrite: t.Optional[bool] = None,
6359    returning: t.Optional[ExpOrStr] = None,
6360    dialect: DialectType = None,
6361    copy: bool = True,
6362    **opts,
6363) -> Insert:
6364    """
6365    Builds an INSERT statement.
6366
6367    Example:
6368        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6369        'INSERT INTO tbl VALUES (1, 2, 3)'
6370
6371    Args:
6372        expression: the sql string or expression of the INSERT statement
6373        into: the tbl to insert data to.
6374        columns: optionally the table's column names.
6375        overwrite: whether to INSERT OVERWRITE or not.
6376        returning: sql conditional parsed into a RETURNING statement
6377        dialect: the dialect used to parse the input expressions.
6378        copy: whether to copy the expression.
6379        **opts: other options to use to parse the input expressions.
6380
6381    Returns:
6382        Insert: the syntax tree for the INSERT statement.
6383    """
6384    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6385    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6386
6387    if columns:
6388        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6389
6390    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6391
6392    if returning:
6393        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6394
6395    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6398def condition(
6399    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6400) -> Condition:
6401    """
6402    Initialize a logical condition expression.
6403
6404    Example:
6405        >>> condition("x=1").sql()
6406        'x = 1'
6407
6408        This is helpful for composing larger logical syntax trees:
6409        >>> where = condition("x=1")
6410        >>> where = where.and_("y=1")
6411        >>> Select().from_("tbl").select("*").where(where).sql()
6412        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6413
6414    Args:
6415        *expression: the SQL code string to parse.
6416            If an Expression instance is passed, this is used as-is.
6417        dialect: the dialect used to parse the input expression (in the case that the
6418            input expression is a SQL string).
6419        copy: Whether to copy `expression` (only applies to expressions).
6420        **opts: other options to use to parse the input expressions (again, in the case
6421            that the input expression is a SQL string).
6422
6423    Returns:
6424        The new Condition instance
6425    """
6426    return maybe_parse(
6427        expression,
6428        into=Condition,
6429        dialect=dialect,
6430        copy=copy,
6431        **opts,
6432    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6435def and_(
6436    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6437) -> Condition:
6438    """
6439    Combine multiple conditions with an AND logical operator.
6440
6441    Example:
6442        >>> and_("x=1", and_("y=1", "z=1")).sql()
6443        'x = 1 AND (y = 1 AND z = 1)'
6444
6445    Args:
6446        *expressions: the SQL code strings to parse.
6447            If an Expression instance is passed, this is used as-is.
6448        dialect: the dialect used to parse the input expression.
6449        copy: whether to copy `expressions` (only applies to Expressions).
6450        **opts: other options to use to parse the input expressions.
6451
6452    Returns:
6453        And: the new condition
6454    """
6455    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))

Combine multiple conditions with an AND logical operator.

Example:
>>> and_("x=1", and_("y=1", "z=1")).sql()
'x = 1 AND (y = 1 AND z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

And: the new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6458def or_(
6459    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6460) -> Condition:
6461    """
6462    Combine multiple conditions with an OR logical operator.
6463
6464    Example:
6465        >>> or_("x=1", or_("y=1", "z=1")).sql()
6466        'x = 1 OR (y = 1 OR z = 1)'
6467
6468    Args:
6469        *expressions: the SQL code strings to parse.
6470            If an Expression instance is passed, this is used as-is.
6471        dialect: the dialect used to parse the input expression.
6472        copy: whether to copy `expressions` (only applies to Expressions).
6473        **opts: other options to use to parse the input expressions.
6474
6475    Returns:
6476        Or: the new condition
6477    """
6478    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))

Combine multiple conditions with an OR logical operator.

Example:
>>> or_("x=1", or_("y=1", "z=1")).sql()
'x = 1 OR (y = 1 OR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

Or: the new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
6481def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6482    """
6483    Wrap a condition with a NOT operator.
6484
6485    Example:
6486        >>> not_("this_suit='black'").sql()
6487        "NOT this_suit = 'black'"
6488
6489    Args:
6490        expression: the SQL code string to parse.
6491            If an Expression instance is passed, this is used as-is.
6492        dialect: the dialect used to parse the input expression.
6493        copy: whether to copy the expression or not.
6494        **opts: other options to use to parse the input expressions.
6495
6496    Returns:
6497        The new condition.
6498    """
6499    this = condition(
6500        expression,
6501        dialect=dialect,
6502        copy=copy,
6503        **opts,
6504    )
6505    return Not(this=_wrap(this, Connector))

Wrap a condition with a NOT operator.

Example:
>>> not_("this_suit='black'").sql()
"NOT this_suit = 'black'"
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression or not.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition.

def paren( expression: Union[str, Expression], copy: bool = True) -> Paren:
6508def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6509    """
6510    Wrap an expression in parentheses.
6511
6512    Example:
6513        >>> paren("5 + 3").sql()
6514        '(5 + 3)'
6515
6516    Args:
6517        expression: the SQL code string to parse.
6518            If an Expression instance is passed, this is used as-is.
6519        copy: whether to copy the expression or not.
6520
6521    Returns:
6522        The wrapped expression.
6523    """
6524    return Paren(this=maybe_parse(expression, copy=copy))

Wrap an expression in parentheses.

Example:
>>> paren("5 + 3").sql()
'(5 + 3)'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • copy: whether to copy the expression or not.
Returns:

The wrapped expression.

SAFE_IDENTIFIER_RE: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6540def to_identifier(name, quoted=None, copy=True):
6541    """Builds an identifier.
6542
6543    Args:
6544        name: The name to turn into an identifier.
6545        quoted: Whether to force quote the identifier.
6546        copy: Whether to copy name if it's an Identifier.
6547
6548    Returns:
6549        The identifier ast node.
6550    """
6551
6552    if name is None:
6553        return None
6554
6555    if isinstance(name, Identifier):
6556        identifier = maybe_copy(name, copy)
6557    elif isinstance(name, str):
6558        identifier = Identifier(
6559            this=name,
6560            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6561        )
6562    else:
6563        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6564    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
6567def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6568    """
6569    Parses a given string into an identifier.
6570
6571    Args:
6572        name: The name to parse into an identifier.
6573        dialect: The dialect to parse against.
6574
6575    Returns:
6576        The identifier ast node.
6577    """
6578    try:
6579        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6580    except ParseError:
6581        expression = to_identifier(name)
6582
6583    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
6589def to_interval(interval: str | Literal) -> Interval:
6590    """Builds an interval expression from a string like '1 day' or '5 months'."""
6591    if isinstance(interval, Literal):
6592        if not interval.is_string:
6593            raise ValueError("Invalid interval string.")
6594
6595        interval = interval.this
6596
6597    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6598
6599    if not interval_parts:
6600        raise ValueError("Invalid interval string.")
6601
6602    return Interval(
6603        this=Literal.string(interval_parts.group(1)),
6604        unit=Var(this=interval_parts.group(2).upper()),
6605    )

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: Union[str, Table, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Optional[Table]:
6616def to_table(
6617    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6618) -> t.Optional[Table]:
6619    """
6620    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6621    If a table is passed in then that table is returned.
6622
6623    Args:
6624        sql_path: a `[catalog].[schema].[table]` string.
6625        dialect: the source dialect according to which the table name will be parsed.
6626        copy: Whether to copy a table if it is passed in.
6627        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6628
6629    Returns:
6630        A table expression.
6631    """
6632    if sql_path is None or isinstance(sql_path, Table):
6633        return maybe_copy(sql_path, copy=copy)
6634    if not isinstance(sql_path, str):
6635        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6636
6637    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6638    if table:
6639        for k, v in kwargs.items():
6640            table.set(k, v)
6641
6642    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6645def to_column(sql_path: str | Column, **kwargs) -> Column:
6646    """
6647    Create a column from a `[table].[column]` sql path. Schema is optional.
6648
6649    If a column is passed in then that column is returned.
6650
6651    Args:
6652        sql_path: `[table].[column]` string
6653    Returns:
6654        Table: A column expression
6655    """
6656    if sql_path is None or isinstance(sql_path, Column):
6657        return sql_path
6658    if not isinstance(sql_path, str):
6659        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6660    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

Create a column from a [table].[column] sql path. Schema is optional.

If a column is passed in then that column is returned.

Arguments:
  • sql_path: [table].[column] string
Returns:

Table: A column expression

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6663def alias_(
6664    expression: ExpOrStr,
6665    alias: t.Optional[str | Identifier],
6666    table: bool | t.Sequence[str | Identifier] = False,
6667    quoted: t.Optional[bool] = None,
6668    dialect: DialectType = None,
6669    copy: bool = True,
6670    **opts,
6671):
6672    """Create an Alias expression.
6673
6674    Example:
6675        >>> alias_('foo', 'bar').sql()
6676        'foo AS bar'
6677
6678        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6679        '(SELECT 1, 2) AS bar(a, b)'
6680
6681    Args:
6682        expression: the SQL code strings to parse.
6683            If an Expression instance is passed, this is used as-is.
6684        alias: the alias name to use. If the name has
6685            special characters it is quoted.
6686        table: Whether to create a table alias, can also be a list of columns.
6687        quoted: whether to quote the alias
6688        dialect: the dialect used to parse the input expression.
6689        copy: Whether to copy the expression.
6690        **opts: other options to use to parse the input expressions.
6691
6692    Returns:
6693        Alias: the aliased expression
6694    """
6695    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6696    alias = to_identifier(alias, quoted=quoted)
6697
6698    if table:
6699        table_alias = TableAlias(this=alias)
6700        exp.set("alias", table_alias)
6701
6702        if not isinstance(table, bool):
6703            for column in table:
6704                table_alias.append("columns", to_identifier(column, quoted=quoted))
6705
6706        return exp
6707
6708    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6709    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6710    # for the complete Window expression.
6711    #
6712    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6713
6714    if "alias" in exp.arg_types and not isinstance(exp, Window):
6715        exp.set("alias", alias)
6716        return exp
6717    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6720def subquery(
6721    expression: ExpOrStr,
6722    alias: t.Optional[Identifier | str] = None,
6723    dialect: DialectType = None,
6724    **opts,
6725) -> Select:
6726    """
6727    Build a subquery expression that's selected from.
6728
6729    Example:
6730        >>> subquery('select x from tbl', 'bar').select('x').sql()
6731        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6732
6733    Args:
6734        expression: the SQL code strings to parse.
6735            If an Expression instance is passed, this is used as-is.
6736        alias: the alias name to use.
6737        dialect: the dialect used to parse the input expression.
6738        **opts: other options to use to parse the input expressions.
6739
6740    Returns:
6741        A new Select instance with the subquery expression included.
6742    """
6743
6744    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6745    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression that's selected from.

Example:
>>> subquery('select x from tbl', 'bar').select('x').sql()
'SELECT x FROM (SELECT x FROM tbl) AS bar'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use.
  • dialect: the dialect used to parse the input expression.
  • **opts: other options to use to parse the input expressions.
Returns:

A new Select instance with the subquery expression included.

def column( col, table=None, db=None, catalog=None, *, fields=None, quoted=None, copy=True):
6776def column(
6777    col,
6778    table=None,
6779    db=None,
6780    catalog=None,
6781    *,
6782    fields=None,
6783    quoted=None,
6784    copy=True,
6785):
6786    """
6787    Build a Column.
6788
6789    Args:
6790        col: Column name.
6791        table: Table name.
6792        db: Database name.
6793        catalog: Catalog name.
6794        fields: Additional fields using dots.
6795        quoted: Whether to force quotes on the column's identifiers.
6796        copy: Whether to copy identifiers if passed in.
6797
6798    Returns:
6799        The new Column instance.
6800    """
6801    this = Column(
6802        this=to_identifier(col, quoted=quoted, copy=copy),
6803        table=to_identifier(table, quoted=quoted, copy=copy),
6804        db=to_identifier(db, quoted=quoted, copy=copy),
6805        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6806    )
6807
6808    if fields:
6809        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6810    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, **opts) -> Cast:
6813def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6814    """Cast an expression to a data type.
6815
6816    Example:
6817        >>> cast('x + 1', 'int').sql()
6818        'CAST(x + 1 AS INT)'
6819
6820    Args:
6821        expression: The expression to cast.
6822        to: The datatype to cast to.
6823        copy: Whether to copy the supplied expressions.
6824
6825    Returns:
6826        The new Cast instance.
6827    """
6828    expression = maybe_parse(expression, copy=copy, **opts)
6829    data_type = DataType.build(to, copy=copy, **opts)
6830    expression = Cast(this=expression, to=data_type)
6831    expression.type = data_type
6832    return expression

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
6835def table_(
6836    table: Identifier | str,
6837    db: t.Optional[Identifier | str] = None,
6838    catalog: t.Optional[Identifier | str] = None,
6839    quoted: t.Optional[bool] = None,
6840    alias: t.Optional[Identifier | str] = None,
6841) -> Table:
6842    """Build a Table.
6843
6844    Args:
6845        table: Table name.
6846        db: Database name.
6847        catalog: Catalog name.
6848        quote: Whether to force quotes on the table's identifiers.
6849        alias: Table's alias.
6850
6851    Returns:
6852        The new Table instance.
6853    """
6854    return Table(
6855        this=to_identifier(table, quoted=quoted) if table else None,
6856        db=to_identifier(db, quoted=quoted) if db else None,
6857        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6858        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6859    )

Build a Table.

Arguments:
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • quote: Whether to force quotes on the table's identifiers.
  • alias: Table's alias.
Returns:

The new Table instance.

def values( values: Iterable[Tuple[Any, ...]], alias: Optional[str] = None, columns: Union[Iterable[str], Dict[str, DataType], NoneType] = None) -> Values:
6862def values(
6863    values: t.Iterable[t.Tuple[t.Any, ...]],
6864    alias: t.Optional[str] = None,
6865    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6866) -> Values:
6867    """Build VALUES statement.
6868
6869    Example:
6870        >>> values([(1, '2')]).sql()
6871        "VALUES (1, '2')"
6872
6873    Args:
6874        values: values statements that will be converted to SQL
6875        alias: optional alias
6876        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6877         If either are provided then an alias is also required.
6878
6879    Returns:
6880        Values: the Values expression object
6881    """
6882    if columns and not alias:
6883        raise ValueError("Alias is required when providing columns")
6884
6885    return Values(
6886        expressions=[convert(tup) for tup in values],
6887        alias=(
6888            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6889            if columns
6890            else (TableAlias(this=to_identifier(alias)) if alias else None)
6891        ),
6892    )

Build VALUES statement.

Example:
>>> values([(1, '2')]).sql()
"VALUES (1, '2')"
Arguments:
  • values: values statements that will be converted to SQL
  • alias: optional alias
  • columns: Optional list of ordered column names or ordered dictionary of column names to types. If either are provided then an alias is also required.
Returns:

Values: the Values expression object

def var( name: Union[str, Expression, NoneType]) -> Var:
6895def var(name: t.Optional[ExpOrStr]) -> Var:
6896    """Build a SQL variable.
6897
6898    Example:
6899        >>> repr(var('x'))
6900        'Var(this=x)'
6901
6902        >>> repr(var(column('x', table='y')))
6903        'Var(this=x)'
6904
6905    Args:
6906        name: The name of the var or an expression who's name will become the var.
6907
6908    Returns:
6909        The new variable node.
6910    """
6911    if not name:
6912        raise ValueError("Cannot convert empty name into var.")
6913
6914    if isinstance(name, Expression):
6915        name = name.name
6916    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table) -> AlterTable:
6919def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6920    """Build ALTER TABLE... RENAME... expression
6921
6922    Args:
6923        old_name: The old name of the table
6924        new_name: The new name of the table
6925
6926    Returns:
6927        Alter table expression
6928    """
6929    old_table = to_table(old_name)
6930    new_table = to_table(new_name)
6931    return AlterTable(
6932        this=old_table,
6933        actions=[
6934            RenameTable(this=new_table),
6935        ],
6936    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None) -> AlterTable:
6939def rename_column(
6940    table_name: str | Table,
6941    old_column_name: str | Column,
6942    new_column_name: str | Column,
6943    exists: t.Optional[bool] = None,
6944) -> AlterTable:
6945    """Build ALTER TABLE... RENAME COLUMN... expression
6946
6947    Args:
6948        table_name: Name of the table
6949        old_column: The old name of the column
6950        new_column: The new name of the column
6951        exists: Whether to add the `IF EXISTS` clause
6952
6953    Returns:
6954        Alter table expression
6955    """
6956    table = to_table(table_name)
6957    old_column = to_column(old_column_name)
6958    new_column = to_column(new_column_name)
6959    return AlterTable(
6960        this=table,
6961        actions=[
6962            RenameColumn(this=old_column, to=new_column, exists=exists),
6963        ],
6964    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
6967def convert(value: t.Any, copy: bool = False) -> Expression:
6968    """Convert a python value into an expression object.
6969
6970    Raises an error if a conversion is not possible.
6971
6972    Args:
6973        value: A python object.
6974        copy: Whether to copy `value` (only applies to Expressions and collections).
6975
6976    Returns:
6977        Expression: the equivalent expression object.
6978    """
6979    if isinstance(value, Expression):
6980        return maybe_copy(value, copy)
6981    if isinstance(value, str):
6982        return Literal.string(value)
6983    if isinstance(value, bool):
6984        return Boolean(this=value)
6985    if value is None or (isinstance(value, float) and math.isnan(value)):
6986        return null()
6987    if isinstance(value, numbers.Number):
6988        return Literal.number(value)
6989    if isinstance(value, bytes):
6990        return HexString(this=value.hex())
6991    if isinstance(value, datetime.datetime):
6992        datetime_literal = Literal.string(
6993            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
6994                sep=" "
6995            )
6996        )
6997        return TimeStrToTime(this=datetime_literal)
6998    if isinstance(value, datetime.date):
6999        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7000        return DateStrToDate(this=date_literal)
7001    if isinstance(value, tuple):
7002        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7003    if isinstance(value, list):
7004        return Array(expressions=[convert(v, copy=copy) for v in value])
7005    if isinstance(value, dict):
7006        return Map(
7007            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7008            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7009        )
7010    raise ValueError(f"Cannot convert {value}")

Convert a python value into an expression object.

Raises an error if a conversion is not possible.

Arguments:
  • value: A python object.
  • copy: Whether to copy value (only applies to Expressions and collections).
Returns:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
7013def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7014    """
7015    Replace children of an expression with the result of a lambda fun(child) -> exp.
7016    """
7017    for k, v in tuple(expression.args.items()):
7018        is_list_arg = type(v) is list
7019
7020        child_nodes = v if is_list_arg else [v]
7021        new_child_nodes = []
7022
7023        for cn in child_nodes:
7024            if isinstance(cn, Expression):
7025                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7026                    new_child_nodes.append(child_node)
7027            else:
7028                new_child_nodes.append(cn)
7029
7030        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))

Replace children of an expression with the result of a lambda fun(child) -> exp.

def replace_tree( expression: Expression, fun: Callable, prune: Optional[Callable[[Expression], bool]] = None) -> Expression:
7033def replace_tree(
7034    expression: Expression,
7035    fun: t.Callable,
7036    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7037) -> Expression:
7038    """
7039    Replace an entire tree with the result of function calls on each node.
7040
7041    This will be traversed in reverse dfs, so leaves first.
7042    If new nodes are created as a result of function calls, they will also be traversed.
7043    """
7044    stack = list(expression.dfs(prune=prune))
7045
7046    while stack:
7047        node = stack.pop()
7048        new_node = fun(node)
7049
7050        if new_node is not node:
7051            node.replace(new_node)
7052
7053            if isinstance(new_node, Expression):
7054                stack.append(new_node)
7055
7056    return new_node

Replace an entire tree with the result of function calls on each node.

This will be traversed in reverse dfs, so leaves first. If new nodes are created as a result of function calls, they will also be traversed.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
7059def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7060    """
7061    Return all table names referenced through columns in an expression.
7062
7063    Example:
7064        >>> import sqlglot
7065        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7066        ['a', 'c']
7067
7068    Args:
7069        expression: expression to find table names.
7070        exclude: a table name to exclude
7071
7072    Returns:
7073        A list of unique names.
7074    """
7075    return {
7076        table
7077        for table in (column.table for column in expression.find_all(Column))
7078        if table and table != exclude
7079    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
7082def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7083    """Get the full name of a table as a string.
7084
7085    Args:
7086        table: Table expression node or string.
7087        dialect: The dialect to generate the table name for.
7088        identify: Determines when an identifier should be quoted. Possible values are:
7089            False (default): Never quote, except in cases where it's mandatory by the dialect.
7090            True: Always quote.
7091
7092    Examples:
7093        >>> from sqlglot import exp, parse_one
7094        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7095        'a.b.c'
7096
7097    Returns:
7098        The table name.
7099    """
7100
7101    table = maybe_parse(table, into=Table, dialect=dialect)
7102
7103    if not table:
7104        raise ValueError(f"Cannot parse {table}")
7105
7106    return ".".join(
7107        (
7108            part.sql(dialect=dialect, identify=True, copy=False)
7109            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7110            else part.name
7111        )
7112        for part in table.parts
7113    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
7116def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7117    """Returns a case normalized table name without quotes.
7118
7119    Args:
7120        table: the table to normalize
7121        dialect: the dialect to use for normalization rules
7122        copy: whether to copy the expression.
7123
7124    Examples:
7125        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7126        'A-B.c'
7127    """
7128    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7129
7130    return ".".join(
7131        p.name
7132        for p in normalize_identifiers(
7133            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7134        ).parts
7135    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
7138def replace_tables(
7139    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7140) -> E:
7141    """Replace all tables in expression according to the mapping.
7142
7143    Args:
7144        expression: expression node to be transformed and replaced.
7145        mapping: mapping of table names.
7146        dialect: the dialect of the mapping table
7147        copy: whether to copy the expression.
7148
7149    Examples:
7150        >>> from sqlglot import exp, parse_one
7151        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7152        'SELECT * FROM c /* a.b */'
7153
7154    Returns:
7155        The mapped expression.
7156    """
7157
7158    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7159
7160    def _replace_tables(node: Expression) -> Expression:
7161        if isinstance(node, Table):
7162            original = normalize_table_name(node, dialect=dialect)
7163            new_name = mapping.get(original)
7164
7165            if new_name:
7166                table = to_table(
7167                    new_name,
7168                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7169                    dialect=dialect,
7170                )
7171                table.add_comments([original])
7172                return table
7173        return node
7174
7175    return expression.transform(_replace_tables, copy=copy)  # type: ignore

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether to copy the expression.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
'SELECT * FROM c /* a.b */'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
7178def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7179    """Replace placeholders in an expression.
7180
7181    Args:
7182        expression: expression node to be transformed and replaced.
7183        args: positional names that will substitute unnamed placeholders in the given order.
7184        kwargs: keyword arguments that will substitute named placeholders.
7185
7186    Examples:
7187        >>> from sqlglot import exp, parse_one
7188        >>> replace_placeholders(
7189        ...     parse_one("select * from :tbl where ? = ?"),
7190        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7191        ... ).sql()
7192        "SELECT * FROM foo WHERE str_col = 'b'"
7193
7194    Returns:
7195        The mapped expression.
7196    """
7197
7198    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7199        if isinstance(node, Placeholder):
7200            if node.name:
7201                new_name = kwargs.get(node.name)
7202                if new_name is not None:
7203                    return convert(new_name)
7204            else:
7205                try:
7206                    return convert(next(args))
7207                except StopIteration:
7208                    pass
7209        return node
7210
7211    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
7214def expand(
7215    expression: Expression,
7216    sources: t.Dict[str, Query],
7217    dialect: DialectType = None,
7218    copy: bool = True,
7219) -> Expression:
7220    """Transforms an expression by expanding all referenced sources into subqueries.
7221
7222    Examples:
7223        >>> from sqlglot import parse_one
7224        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7225        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7226
7227        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7228        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7229
7230    Args:
7231        expression: The expression to expand.
7232        sources: A dictionary of name to Queries.
7233        dialect: The dialect of the sources dict.
7234        copy: Whether to copy the expression during transformation. Defaults to True.
7235
7236    Returns:
7237        The transformed expression.
7238    """
7239    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7240
7241    def _expand(node: Expression):
7242        if isinstance(node, Table):
7243            name = normalize_table_name(node, dialect=dialect)
7244            source = sources.get(name)
7245            if source:
7246                subquery = source.subquery(node.alias or name)
7247                subquery.comments = [f"source: {name}"]
7248                return subquery.transform(_expand, copy=False)
7249        return node
7250
7251    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
7254def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7255    """
7256    Returns a Func expression.
7257
7258    Examples:
7259        >>> func("abs", 5).sql()
7260        'ABS(5)'
7261
7262        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7263        'CAST(5 AS DOUBLE)'
7264
7265    Args:
7266        name: the name of the function to build.
7267        args: the args used to instantiate the function of interest.
7268        copy: whether to copy the argument expressions.
7269        dialect: the source dialect.
7270        kwargs: the kwargs used to instantiate the function of interest.
7271
7272    Note:
7273        The arguments `args` and `kwargs` are mutually exclusive.
7274
7275    Returns:
7276        An instance of the function of interest, or an anonymous function, if `name` doesn't
7277        correspond to an existing `sqlglot.expressions.Func` class.
7278    """
7279    if args and kwargs:
7280        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7281
7282    from sqlglot.dialects.dialect import Dialect
7283
7284    dialect = Dialect.get_or_raise(dialect)
7285
7286    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7287    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7288
7289    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7290    if constructor:
7291        if converted:
7292            if "dialect" in constructor.__code__.co_varnames:
7293                function = constructor(converted, dialect=dialect)
7294            else:
7295                function = constructor(converted)
7296        elif constructor.__name__ == "from_arg_list":
7297            function = constructor.__self__(**kwargs)  # type: ignore
7298        else:
7299            constructor = FUNCTION_BY_NAME.get(name.upper())
7300            if constructor:
7301                function = constructor(**kwargs)
7302            else:
7303                raise ValueError(
7304                    f"Unable to convert '{name}' into a Func. Either manually construct "
7305                    "the Func expression of interest or parse the function call."
7306                )
7307    else:
7308        kwargs = kwargs or {"expressions": converted}
7309        function = Anonymous(this=name, **kwargs)
7310
7311    for error_message in function.error_messages(converted):
7312        raise ValueError(error_message)
7313
7314    return function

Returns a Func expression.

Examples:
>>> func("abs", 5).sql()
'ABS(5)'
>>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
'CAST(5 AS DOUBLE)'
Arguments:
  • name: the name of the function to build.
  • args: the args used to instantiate the function of interest.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Note:

The arguments args and kwargs are mutually exclusive.

Returns:

An instance of the function of interest, or an anonymous function, if name doesn't correspond to an existing Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
7317def case(
7318    expression: t.Optional[ExpOrStr] = None,
7319    **opts,
7320) -> Case:
7321    """
7322    Initialize a CASE statement.
7323
7324    Example:
7325        case().when("a = 1", "foo").else_("bar")
7326
7327    Args:
7328        expression: Optionally, the input expression (not all dialects support this)
7329        **opts: Extra keyword arguments for parsing `expression`
7330    """
7331    if expression is not None:
7332        this = maybe_parse(expression, **opts)
7333    else:
7334        this = None
7335    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def cast_unless( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], *types: Union[str, DataType, DataType.Type], **opts: Any) -> Expression | Cast:
7338def cast_unless(
7339    expression: ExpOrStr,
7340    to: DATA_TYPE,
7341    *types: DATA_TYPE,
7342    **opts: t.Any,
7343) -> Expression | Cast:
7344    """
7345    Cast an expression to a data type unless it is a specified type.
7346
7347    Args:
7348        expression: The expression to cast.
7349        to: The data type to cast to.
7350        **types: The types to exclude from casting.
7351        **opts: Extra keyword arguments for parsing `expression`
7352    """
7353    expr = maybe_parse(expression, **opts)
7354    if expr.is_type(*types):
7355        return expr
7356    return cast(expr, to, **opts)

Cast an expression to a data type unless it is a specified type.

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7359def array(
7360    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7361) -> Array:
7362    """
7363    Returns an array.
7364
7365    Examples:
7366        >>> array(1, 'x').sql()
7367        'ARRAY(1, x)'
7368
7369    Args:
7370        expressions: the expressions to add to the array.
7371        copy: whether to copy the argument expressions.
7372        dialect: the source dialect.
7373        kwargs: the kwargs used to instantiate the function of interest.
7374
7375    Returns:
7376        An array expression.
7377    """
7378    return Array(
7379        expressions=[
7380            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7381            for expression in expressions
7382        ]
7383    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
7386def tuple_(
7387    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7388) -> Tuple:
7389    """
7390    Returns an tuple.
7391
7392    Examples:
7393        >>> tuple_(1, 'x').sql()
7394        '(1, x)'
7395
7396    Args:
7397        expressions: the expressions to add to the tuple.
7398        copy: whether to copy the argument expressions.
7399        dialect: the source dialect.
7400        kwargs: the kwargs used to instantiate the function of interest.
7401
7402    Returns:
7403        A tuple expression.
7404    """
7405    return Tuple(
7406        expressions=[
7407            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7408            for expression in expressions
7409        ]
7410    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
7413def true() -> Boolean:
7414    """
7415    Returns a true Boolean expression.
7416    """
7417    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7420def false() -> Boolean:
7421    """
7422    Returns a false Boolean expression.
7423    """
7424    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7427def null() -> Null:
7428    """
7429    Returns a Null expression.
7430    """
7431    return Null()

Returns a Null expression.

NONNULL_CONSTANTS = (<class 'Literal'>, <class 'Boolean'>)
CONSTANTS = (<class 'Literal'>, <class 'Boolean'>, <class 'Null'>)